View source
<?php
require_once 'uc_attribute.ca.inc';
function uc_attribute_help($path, $arg) {
switch ($path) {
case 'node/%/edit/attributes':
return t('Add attributes to this product using the <a href="!url">add attributes form</a>. You may then adjust the settings for these attributes on this page and go on to configure their options in the <em>Options</em> tab.', array(
'!url' => url('node/' . $arg[1] . '/edit/attributes/add'),
));
case 'admin/store/products/classes/%/attributes':
return t('Add attributes to the product class using the <a href="!url">add attributes form</a>. You may then adjust the settings for these attributes on this page and go on to configure their options in the <em>Options</em> tab.', array(
'!url' => url('admin/store/products/classes/' . $arg[4] . '/attributes/add'),
));
case 'node/%/edit/attributes/add':
case 'admin/store/products/classes/%/attributes/add':
return t('Select the attributes you want to add and submit the form.');
case 'node/%/edit/options':
case 'admin/store/products/classes/%/options':
return '<p>' . t('Use the checkboxes to enable options for attributes and the radio buttons to specify the default option. Attributes with no enabled options will be displayed as text fields. Drag and drop the options to reorder them.') . '</p><p>' . t('The cost, price and weight fields will make adjustments against the original product, so you may enter positive or negative amounts here, or enter 0 if the option should make no adjustment.') . '</p>';
case 'node/%/edit/adjustments':
return t('Enter an alternate SKU to be used when the specified set of options are chosen and the product is added to the cart. <b>Warning:</b> Adding or removing attributes from this product will reset all the SKUs on this page to the default product SKU.');
case 'admin/store/products/classes/%/attributes_bulk':
return t('Bulk updates performed here will reset all attributes and options on the selected products to the current defaults for this product class.<p><em><strong>Warning:</strong> any product level customizations will be lost!</em></p>To perform bulk updates on specific option values without resetting attributes to the class defaults, go to <a href="!url">Store administration->Attributes</a> and edit the option, selecting the checkbox to update existing products.', array(
'!url' => url('admin/store/attributes'),
));
}
}
function uc_attribute_menu() {
$items['admin/store/attributes'] = array(
'title' => 'Attributes',
'description' => 'Create and edit attributes and options.',
'page callback' => 'uc_attribute_admin',
'access arguments' => array(
'administer attributes',
),
'type' => MENU_NORMAL_ITEM,
'weight' => -1,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/overview'] = array(
'title' => 'Overview',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/store/attributes/add'] = array(
'title' => 'Add an attribute',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_form',
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/settings/attributes'] = array(
'title' => 'Attribute settings',
'description' => 'Configure the attribute settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_admin_settings',
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/%uc_attribute/edit'] = array(
'title' => 'Edit attribute',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_form',
3,
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_CALLBACK,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/%uc_attribute/delete'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_delete_confirm',
3,
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_CALLBACK,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/%uc_attribute/options'] = array(
'title' => 'Options',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_options_form',
3,
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_CALLBACK,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/%uc_attribute/options/overview'] = array(
'title' => 'Overview',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/%uc_attribute/options/add'] = array(
'title' => 'Add an option',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_option_form',
3,
NULL,
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/%uc_attribute/options/%uc_attribute_option/edit'] = array(
'title' => 'Edit option',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_option_form',
3,
5,
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_CALLBACK,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/attributes/%uc_attribute/options/%uc_attribute_option/delete'] = array(
'title' => 'Delete option',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_option_delete_confirm',
3,
5,
),
'access arguments' => array(
'administer attributes',
),
'type' => MENU_CALLBACK,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/products/classes/%uc_product_class/attributes'] = array(
'title' => 'Attributes',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_object_attributes_form',
4,
'class',
),
'access callback' => 'uc_attribute_product_class_access',
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/products/classes/%uc_product_class/options'] = array(
'title' => 'Options',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_object_options_form',
4,
'class',
),
'access callback' => 'uc_attribute_product_class_access',
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'uc_attribute.admin.inc',
);
$items['admin/store/products/classes/%uc_product_class/attributes_bulk'] = array(
'title' => 'Bulk',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_bulk_update_form',
4,
'class',
),
'access callback' => 'uc_attribute_product_class_access',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
'file' => 'uc_attribute.admin.inc',
);
$items['node/%node/edit/attributes'] = array(
'title' => 'Attributes',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_object_attributes_form',
1,
'product',
'overview',
),
'access callback' => 'uc_attribute_product_access',
'access arguments' => array(
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'file' => 'uc_attribute.admin.inc',
);
$items['node/%node/edit/attributes/add'] = array(
'title' => 'Attributes',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_object_attributes_form',
1,
'product',
'add',
),
'access callback' => 'uc_attribute_product_access',
'access arguments' => array(
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'file' => 'uc_attribute.admin.inc',
);
$items['node/%node/edit/attributes/reset'] = array(
'title' => 'Reset to defaults',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_attribute_node_reset_confirm',
1,
),
'access callback' => 'uc_attribute_product_access',
'access arguments' => array(
1,
),
'type' => MENU_CALLBACK,
'file' => 'uc_attribute.admin.inc',
);
$items['node/%node/edit/options'] = array(
'title' => 'Options',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_object_options_form',
1,
'product',
),
'access callback' => 'uc_attribute_product_option_access',
'access arguments' => array(
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'uc_attribute.admin.inc',
);
$items['node/%node/edit/adjustments'] = array(
'title' => 'Adjustments',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'uc_product_adjustments_form',
1,
),
'access callback' => 'uc_attribute_product_option_access',
'access arguments' => array(
1,
),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
'file' => 'uc_attribute.admin.inc',
);
return $items;
}
function uc_attribute_product_class_access() {
return user_access('administer product classes') && user_access('administer attributes');
}
function uc_attribute_product_access($node) {
if ($node->type == 'product_kit') {
return FALSE;
}
return uc_product_is_product($node) && node_access('update', $node) && (user_access('administer attributes') || user_access('administer product attributes'));
}
function uc_attribute_product_option_access($node) {
if ($node->type == 'product_kit') {
return FALSE;
}
return uc_product_is_product($node) && node_access('update', $node) && (user_access('administer attributes') || user_access('administer product attributes') || user_access('administer product options'));
}
function uc_attribute_perm() {
return array(
'administer attributes',
'administer product attributes',
'administer product options',
);
}
function uc_attribute_init() {
drupal_add_css(drupal_get_path('module', 'uc_attribute') . '/uc_attribute.css');
}
function uc_attribute_theme() {
return array(
'uc_attribute_option' => array(
'arguments' => array(
'option' => '',
'price' => '',
),
),
'uc_attribute_add_to_cart' => array(
'arguments' => array(
'form' => NULL,
),
),
'uc_object_attributes_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'uc_attribute.admin.inc',
),
'uc_object_options_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'uc_attribute.admin.inc',
),
'uc_attribute_options_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'uc_attribute.admin.inc',
),
'uc_product_attributes' => array(
'arguments' => array(
'product' => NULL,
),
'file' => 'uc_attribute.admin.inc',
),
'uc_attribute_bulk_update_form' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'uc_attribute.admin.inc',
),
);
}
function uc_attribute_form_alter(&$form, $form_state, $form_id) {
if (strpos($form_id, 'add_product_form')) {
$node =& $form['node']['#value'];
if (isset($form['sub_products']) && count(element_children($form['sub_products']))) {
foreach (element_children($form['sub_products']) as $key) {
$form['sub_products'][$key]['attributes'] = _uc_attribute_alter_form(node_load($key));
if (is_array($form['sub_products'][$key]['attributes'])) {
$form['sub_products'][$key]['attributes']['#tree'] = TRUE;
$form['sub_products'][$key]['#type'] = 'fieldset';
}
}
}
else {
$form['attributes'] = _uc_attribute_alter_form($node);
if (is_array($form['attributes'])) {
$form['attributes']['#tree'] = TRUE;
$form['attributes']['#weight'] = -1;
}
}
}
}
function uc_attribute_uc_form_alter(&$form, &$form_state, $form_id) {
if (strpos($form_id, 'add_to_cart_form') || strpos($form_id, 'add_product_form')) {
$node =& $form['node']['#value'];
if (isset($form['products']) && count(element_children($form['products']))) {
foreach (element_children($form['products']) as $key) {
$form['products'][$key]['attributes'] = _uc_attribute_alter_form(node_load($key));
if (is_array($form['products'][$key]['attributes'])) {
$form['products'][$key]['attributes']['#tree'] = TRUE;
$form['products'][$key]['#type'] = 'fieldset';
}
}
}
else {
$form['attributes'] = _uc_attribute_alter_form($node);
if (is_array($form['attributes'])) {
$form['attributes']['#tree'] = TRUE;
$form['attributes']['#weight'] = -1;
}
}
}
}
function uc_attribute_nodeapi(&$node, $op, $arg3 = NULL, $arg4 = NULL) {
if (uc_product_is_product($node->type)) {
switch ($op) {
case 'load':
$attributes = uc_product_get_attributes($node->nid);
if (is_array($attributes) && !empty($attributes)) {
$node->attributes = $attributes;
return array(
'attributes' => $attributes,
);
}
break;
case 'insert':
uc_attribute_node_insert($node);
break;
case 'delete':
uc_attribute_node_delete($node);
break;
case 'update index':
$output = '';
$attributes = uc_product_get_attributes($node->nid);
foreach ($attributes as $attribute) {
$output .= '<h3>' . _uc_attribute_get_name($attribute) . '</h3>';
foreach ($attribute->options as $option) {
$output .= $option->name . ' ';
}
$output .= "\n";
}
$result = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = %d", $node->nid);
while ($adjustment = db_fetch_object($result)) {
$output .= '<h2>' . $adjustment->model . "</h2>\n";
}
return $output;
}
}
}
function uc_attribute_node_insert($node) {
switch ($GLOBALS['db_type']) {
case 'mysqli':
case 'mysql':
db_query("INSERT IGNORE INTO {uc_product_attributes} (nid, aid, label, ordering, required, display, default_option) SELECT %d, aid, label, ordering, required, display, default_option FROM {uc_class_attributes} WHERE pcid = '%s'", $node->nid, $node->type);
db_query("INSERT IGNORE INTO {uc_product_options} (nid, oid, cost, price, weight, ordering) SELECT %d, oid, cost, price, weight, ordering FROM {uc_class_attribute_options} WHERE pcid = '%s'", $node->nid, $node->type);
break;
case 'pgsql':
db_query("INSERT INTO {uc_product_attributes} (nid, aid, label, ordering, required, display, default_option) SELECT %d, aid, label, ordering, required, display, default_option FROM {uc_class_attributes} WHERE pcid = '%s'", $node->nid, $node->type);
db_query("INSERT INTO {uc_product_options} (nid, oid, cost, price, weight, ordering) SELECT %d, oid, cost, price, weight, ordering FROM {uc_class_attribute_options} WHERE pcid = '%s'", $node->nid, $node->type);
break;
}
}
function uc_attribute_node_delete($node) {
db_query("DELETE FROM {uc_product_options} WHERE nid = %d", $node->nid);
db_query("DELETE FROM {uc_product_adjustments} WHERE nid = %d", $node->nid);
db_query("DELETE FROM {uc_product_attributes} WHERE nid = %d", $node->nid);
}
function uc_attribute_node_reset($node) {
uc_attribute_node_delete($node);
uc_attribute_node_insert($node);
}
function uc_attribute_locale($op = 'groups') {
switch ($op) {
case 'groups':
return array(
'uc_attribute' => t('Ubercart attributes'),
);
case 'info':
$info['uc_attribute']['refresh callback'] = 'uc_attribute_locale_refresh';
$info['uc_attribute']['format'] = FALSE;
return $info;
}
}
function uc_attribute_locale_refresh() {
$attributes = db_query("SELECT aid, name, label, description FROM {uc_attributes}");
while ($attribute = db_fetch_object($attributes)) {
i18nstrings_update('uc_attribute:attribute:' . $attribute->aid . ':name', $attribute->name);
i18nstrings_update('uc_attribute:attribute:' . $attribute->aid . ':label', $attribute->label);
i18nstrings_update('uc_attribute:attribute:' . $attribute->aid . ':description', $attribute->description);
$options = db_query("SELECT oid, name FROM {uc_attribute_options} WHERE aid = %d", array(
$attribute->aid,
));
while ($option = db_fetch_object($options)) {
i18nstrings_update('uc_attribute:option:' . $option->oid . ':name', $option->name);
}
}
return TRUE;
}
function uc_attribute_translate(&$attribute) {
if (function_exists('i18nstrings')) {
$attribute->name = i18nstrings('uc_attribute:attribute:' . $attribute->aid . ':name', $attribute->name);
$attribute->label = i18nstrings('uc_attribute:attribute:' . $attribute->aid . ':label', $attribute->label);
$attribute->description = i18nstrings('uc_attribute:attribute:' . $attribute->aid . ':description', $attribute->description);
foreach ($attribute->options as &$option) {
$option->name = i18nstrings('uc_attribute:option:' . $option->oid . ':name', $option->name);
}
}
}
function uc_attribute_uc_product_models($nid) {
$models = array();
$adjustments = db_query("SELECT DISTINCT model FROM {uc_product_adjustments} WHERE nid = %d", $nid);
while ($adjustment = db_result($adjustments)) {
$models[] = $adjustment;
}
return $models;
}
function uc_attribute_add_to_cart_data($form_values) {
if (isset($form_values['attributes'])) {
return array(
'attributes' => $form_values['attributes'],
);
}
else {
return array(
'attributes' => array(),
);
}
}
function uc_attribute_order_product_alter(&$product, $order) {
if (!empty($product->data['attributes'])) {
$attributes_keys = array_keys($product->data['attributes']);
if (is_numeric(array_shift($attributes_keys))) {
$attributes = array();
$options = _uc_cart_product_get_options($product);
foreach ($options as $aid => $option) {
$attributes[$option['attribute']][$option['oid']] = $option['name'];
}
$product->data['attributes'] = $attributes;
}
}
}
function uc_attribute_product_class($type, $op) {
switch ($op) {
case 'delete':
db_query("DELETE FROM {uc_class_attributes} WHERE pcid = '%s'", $type);
db_query("DELETE FROM {uc_class_attribute_options} WHERE pcid = '%s'", $type);
break;
}
}
function uc_attribute_cart_item($op, &$item) {
switch ($op) {
case 'load':
$options = _uc_cart_product_get_options($item);
$op_costs = 0;
$op_prices = 0;
$op_weight = 0;
foreach ($options as $option) {
$op_costs += $option['cost'];
$op_prices += $option['price'];
$op_weight += $option['weight'];
}
$item->cost += $op_costs;
$item->price += $op_prices;
$item->weight += $op_weight;
$combination = array();
foreach ((array) $item->data['attributes'] as $aid => $value) {
if (is_numeric($value)) {
$attribute = uc_attribute_load($aid, $item->nid, 'product');
if ($attribute && ($attribute->display == 1 || $attribute->display == 2)) {
$combination[$aid] = $value;
}
}
}
ksort($combination);
$result = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = %d AND combination LIKE '%s'", $item->nid, serialize($combination));
$model = db_result($result);
if (!empty($model)) {
$item->model = $model;
}
break;
}
}
function uc_attribute_product_description($product) {
$description = array(
'attributes' => array(
'#product' => array(
'#type' => 'value',
'#value' => $product,
),
'#theme' => 'uc_product_attributes',
'#weight' => 1,
),
);
$desc =& $description['attributes'];
$weight = 0;
if (empty($product->order_id)) {
foreach (_uc_cart_product_get_options($product) as $option) {
if (!isset($desc[$option['aid']])) {
$desc[$option['aid']]['#attribute_name'] = $option['attribute'];
$desc[$option['aid']]['#options'] = array(
$option['name'],
);
}
else {
$desc[$option['aid']]['#options'][] = $option['name'];
}
$desc[$option['aid']]['#weight'] = $weight++;
}
}
else {
foreach ((array) $product->data['attributes'] as $attribute => $option) {
$desc[] = array(
'#attribute_name' => $attribute,
'#options' => $option,
'#weight' => $weight++,
);
}
}
return $description;
}
function uc_attribute_load_multiple($aids = array(), $type = '', $id = NULL) {
$sql = uc_attribute_type_info($type);
$conditions = array();
if (!empty($aids)) {
$conditions[] = "ua.aid IN (" . implode(", ", array_filter($aids, 'is_numeric')) . ")";
}
if (!empty($type)) {
$conditions[] = "uca.{$sql['id']} = {$sql['placeholder']}";
$conditions = implode(" AND", $conditions);
$result = db_query("\n SELECT uca.aid\n FROM {$sql['attr_table']} AS uca\n LEFT JOIN {uc_attributes} AS ua ON uca.aid = ua.aid\n WHERE {$conditions}\n ORDER BY uca.ordering, ua.name", $id);
}
else {
$conditions[] = "1";
$conditions = implode(" AND ", $conditions);
$result = db_query("SELECT aid FROM {uc_attributes} ua WHERE {$conditions} ORDER BY ordering, name");
}
$attributes = array();
while ($aid = db_result($result)) {
$attributes[$aid] = uc_attribute_load($aid, $id, $type);
}
return $attributes;
}
function uc_attribute_load($aid, $id = NULL, $type = '') {
$sql = uc_attribute_type_info($type);
switch ($type) {
case 'product':
case 'class':
$attribute = db_fetch_object(db_query("\n SELECT a.aid, a.name, a.label AS default_label, a.ordering AS default_ordering,\n a.required AS default_required, a.display AS default_display,\n a.description, pa.label, pa.default_option, pa.required, pa.ordering,\n pa.display, pa.{$sql['id']}\n FROM {uc_attributes} AS a\n LEFT JOIN {$sql['attr_table']} AS pa ON a.aid = pa.aid AND\n pa.{$sql['id']} = {$sql['placeholder']}\n WHERE a.aid = %d", $id, $aid));
if (!$attribute) {
return FALSE;
}
foreach (array(
'ordering',
'required',
'display',
'label',
) as $field) {
if (isset($attribute->{"default_{$field}"}) && is_null($attribute->{$field})) {
$attribute->{$field} = $attribute->{"default_{$field}"};
}
}
if (empty($attribute->label)) {
$attribute->label = $attribute->name;
}
$result = db_query("\n SELECT po.{$sql['id']}, po.oid, po.cost, po.price, po.weight, po.ordering, ao.name,\n ao.aid\n FROM {$sql['opt_table']} AS po\n LEFT JOIN {uc_attribute_options} AS ao ON po.oid = ao.oid AND\n po.{$sql['id']} = {$sql['placeholder']}\n WHERE aid = %d ORDER BY po.ordering, ao.name", $id, $aid);
break;
default:
$attribute = db_fetch_object(db_query("SELECT * FROM {uc_attributes} WHERE aid = %d", $aid));
$result = db_query("SELECT * FROM {uc_attribute_options} WHERE aid = %d ORDER BY ordering, name", $aid);
if (!$attribute) {
return FALSE;
}
break;
}
if ($attribute) {
$attribute->options = array();
while ($option = db_fetch_object($result)) {
$attribute->options[$option->oid] = $option;
}
uc_attribute_translate($attribute);
}
return $attribute;
}
function uc_attribute_load_product_attributes($nid) {
return uc_attribute_load_multiple(array(), 'product', $nid);
}
function uc_attribute_save(&$attribute) {
$key = empty($attribute->aid) ? NULL : 'aid';
return drupal_write_record('uc_attributes', $attribute, $key);
}
function uc_attribute_delete($aid) {
uc_attribute_subject_delete($aid, 'class');
uc_attribute_subject_delete($aid, 'product');
db_query("DELETE FROM {uc_attribute_options} WHERE aid = %d", $aid);
db_query("DELETE FROM {uc_attributes} WHERE aid = %d", $aid);
return SAVED_DELETED;
}
function uc_attribute_option_load($oid) {
return db_fetch_object(db_query("SELECT * FROM {uc_attribute_options} WHERE oid = %d", $oid));
}
function uc_attribute_option_save(&$option) {
$key = empty($option->oid) ? NULL : 'oid';
return drupal_write_record('uc_attribute_options', $option, $key);
}
function uc_attribute_option_delete($oid) {
uc_attribute_subject_option_delete($oid, 'class');
uc_attribute_subject_option_delete($oid, 'product');
db_query("DELETE FROM {uc_attribute_options} WHERE oid = %d", $oid);
return SAVED_DELETED;
}
function uc_attribute_subject_save(&$attribute, $type, $id, $save_options = FALSE) {
$sql = uc_attribute_type_info($type);
$key = uc_attribute_subject_exists($attribute->aid, $type, $id) ? array(
'aid',
$sql['id'],
) : NULL;
if ($save_options && is_array($attribute->options)) {
foreach ($attribute->options as $option) {
$option = (object) $option;
uc_attribute_subject_option_save($option, $type, $id);
}
if (empty($key)) {
$default_option = 0;
if (is_array($attribute->options)) {
$option = (object) reset($attribute->options);
$default_option = $option->oid;
}
$attribute->default_option = $default_option;
}
}
$attribute->{$type == 'product' ? 'nid' : 'pcid'} = $id;
$result = drupal_write_record(trim($sql['attr_table'], '{}'), $attribute, $key);
return $result;
}
function uc_attribute_subject_delete($aid, $type, $id = NULL) {
$sql = uc_attribute_type_info($type);
$conditions[] = "aid = %d";
if ($id) {
$conditions[] = "{$sql['id']} = {$sql['placeholder']}";
}
$conditions = implode(" AND ", $conditions);
$result = db_query("SELECT a.oid FROM {uc_attribute_options} AS a JOIN {$sql['opt_table']} AS subject ON a.oid = subject.oid WHERE {$conditions}", $aid, $id);
while ($oid = db_result($result)) {
uc_attribute_subject_option_delete($oid, $type, $id, FALSE);
}
db_query("DELETE FROM {$sql['attr_table']} WHERE {$conditions}", $aid, $id);
if ($type == 'product') {
uc_attribute_adjustments_delete(array(
'aid' => $aid,
'nid' => $id,
));
}
return SAVED_DELETED;
}
function uc_attribute_subject_option_load($oid, $type, $id) {
$sql = uc_attribute_type_info($type);
$result = db_query("\n SELECT po.{$sql['id']}, po.oid, po.cost, po.price, po.weight, po.ordering, ao.name,\n ao.aid\n FROM {$sql['opt_table']} AS po\n LEFT JOIN {uc_attribute_options} AS ao ON po.oid = ao.oid\n WHERE po.oid = %d AND\n po.{$sql['id']} = {$sql['placeholder']}\n ORDER BY po.ordering, ao.name", $oid, $id);
return db_fetch_object($result);
}
function uc_attribute_subject_option_save(&$option, $type, $id) {
$sql = uc_attribute_type_info($type);
$key = uc_attribute_subject_option_exists($option->oid, $type, $id) ? array(
'oid',
$sql['id'],
) : NULL;
$option->{$type == 'product' ? 'nid' : 'pcid'} = $id;
$result = drupal_write_record(trim($sql['opt_table'], '{}'), $option, $key);
return $result;
}
function uc_attribute_subject_option_delete($oid, $type, $id = NULL, $adjustments = TRUE) {
$sql = uc_attribute_type_info($type);
$conditions[] = "oid = %d";
if ($id) {
$conditions[] = "{$sql['id']} = {$sql['placeholder']}";
}
$conditions = implode(" AND ", $conditions);
db_query("DELETE FROM {$sql['opt_table']} WHERE {$conditions}", $oid, $id);
if ($adjustments && $type == 'product') {
uc_attribute_adjustments_delete(array(
'aid' => uc_attribute_option_load($oid)->aid,
'oid' => $oid,
'nid' => $id,
));
}
return SAVED_DELETED;
}
function uc_attribute_adjustments_delete($fields) {
$match = '';
if (!empty($fields['aid'])) {
$match .= serialize((int) $fields['aid']);
}
if (!empty($fields['oid'])) {
$match .= serialize((string) $fields['oid']);
}
$args = $conditions = array();
if ($match) {
$conditions[] = "combination LIKE '%%%s%%'";
$args[] = $match;
}
if (!empty($fields['nid'])) {
$conditions[] = "nid = %d";
$args[] = $fields['nid'];
}
$conditions = implode(" AND ", $conditions);
if ($conditions) {
db_query("DELETE FROM {uc_product_adjustments} WHERE {$conditions}", $args);
}
return SAVED_DELETED;
}
function uc_attribute_subject_exists($aid, $type, $id) {
$sql = uc_attribute_type_info($type);
return FALSE !== db_result(db_query("SELECT aid FROM {$sql['attr_table']} WHERE aid = %d AND {$sql['id']} = {$sql['placeholder']}", $aid, $id));
}
function uc_attribute_subject_option_exists($oid, $type, $id) {
$sql = uc_attribute_type_info($type);
return FALSE !== db_result(db_query("SELECT oid FROM {$sql['opt_table']} WHERE oid = %d AND {$sql['id']} = {$sql['placeholder']}", $oid, $id));
}
function uc_attribute_type_info($type) {
switch ($type) {
case 'product':
return array(
'attr_table' => '{uc_product_attributes}',
'opt_table' => '{uc_product_options}',
'id' => 'nid',
'placeholder' => '%d',
);
break;
case 'class':
return array(
'attr_table' => '{uc_class_attributes}',
'opt_table' => '{uc_class_attribute_options}',
'id' => 'pcid',
'placeholder' => "'%s'",
);
break;
}
}
function uc_product_get_attributes($nid) {
$attributes = array();
$result = db_query("SELECT upa.aid FROM {uc_product_attributes} AS upa LEFT JOIN {uc_attributes} AS ua ON upa.aid = ua.aid WHERE upa.nid = %d ORDER BY upa.ordering, ua.name", $nid);
while ($attribute = db_fetch_object($result)) {
$attributes[$attribute->aid] = uc_attribute_load($attribute->aid, $nid, 'product');
}
return $attributes;
}
function uc_class_get_attributes($pcid) {
$attributes = array();
$result = db_query("SELECT uca.aid FROM {uc_class_attributes} AS uca LEFT JOIN {uc_attributes} AS ua ON uca.aid = ua.aid WHERE uca.pcid = '%s' ORDER BY uca.ordering, ua.name", $pcid);
while ($attribute = db_fetch_object($result)) {
$attributes[$attribute->aid] = uc_attribute_load($attribute->aid, $pcid, 'class');
}
return $attributes;
}
function _uc_cart_product_get_options($item) {
$options = array();
$data = $item->data;
$node = node_load($item->nid);
$index = 0;
if (!empty($data['attributes']) && is_array($data['attributes'])) {
foreach ($data['attributes'] as $aid => $selected) {
if (isset($node->attributes[$aid])) {
$attribute = $node->attributes[$aid];
$name = _uc_attribute_get_name($attribute);
if ($attribute->display && count($attribute->options)) {
foreach ((array) $selected as $oid) {
if ($oid > 0) {
$options[$index] = (array) $attribute->options[$oid];
$options[$index]['attribute'] = $name;
$index++;
}
}
}
else {
$options[$index] = array(
'attribute' => $name,
'aid' => $aid,
'oid' => 0,
'name' => $selected,
'cost' => 0,
'price' => 0,
'weight' => 0,
);
}
$index++;
}
}
}
else {
$options = array();
}
return $options;
}
function _uc_attribute_alter_form($product) {
if (!isset($product->attributes)) {
$product->attributes = uc_product_get_attributes($product->nid);
}
if (!is_array($product->attributes) || empty($product->attributes)) {
return NULL;
}
$nid = $product->nid;
$priced_attributes = uc_attribute_priced_attributes($nid);
$attributes = $product->attributes;
$form_attributes = array();
$context = array(
'revision' => 'formatted',
);
foreach ($attributes as $attribute) {
$context['subject']['attribute'] = $attribute;
$options = array();
foreach ($attribute->options as $option) {
$context['subject']['option'] = $option;
$display_price = '';
if (in_array($attribute->aid, $priced_attributes)) {
switch (variable_get('uc_attribute_option_price_format', 'adjustment')) {
case 'total':
$context['type'] = 'product';
$context['subject']['node'] = $product;
if (count($priced_attributes) == 1 && $attribute->display != 3) {
$display_price = uc_price($product->sell_price + $option->price, $context);
break;
}
case 'adjustment':
$context['type'] = 'attribute_option';
if ($option->price != 0) {
$display_price = $option->price > 0 ? '+' : '-';
$display_price .= uc_price(abs($option->price), $context);
}
break;
}
}
$options[$option->oid] = theme('uc_attribute_option', $attribute->display == 2 ? check_plain($option->name) : $option->name, $display_price);
}
if (count($attribute->options) && $attribute->display > 0) {
if ($attribute->required) {
if ($attribute->display == 1) {
$options = array(
'' => t('Please select'),
) + $options;
}
$attribute->default_option = '';
}
$attr_type = '';
switch ($attribute->display) {
case 1:
$attr_type = 'select';
break;
case 2:
$attr_type = 'radios';
break;
case 3:
$attr_type = 'checkboxes';
break;
}
$form_attributes[$attribute->aid] = array(
'#type' => $attr_type,
'#description' => check_markup($attribute->description),
'#default_value' => $attr_type == "checkboxes" ? array() : $attribute->default_option,
'#options' => $options,
'#required' => $attribute->required,
);
}
else {
$form_attributes[$attribute->aid] = array(
'#type' => 'textfield',
'#description' => check_markup($attribute->description),
'#default_value' => '',
'#required' => $attribute->required,
);
if (!$attribute->required && isset($attribute->options[$attribute->default_option])) {
$form_attributes[$attribute->aid]['#default_value'] = $attribute->options[$attribute->default_option]->name;
}
}
$name = _uc_attribute_get_name($attribute, FALSE);
if (!is_null($name)) {
$form_attributes[$attribute->aid]['#title'] = check_plain($name);
}
$form_attributes['#theme'] = 'uc_attribute_add_to_cart';
}
return $form_attributes;
}
function _uc_attribute_display_types() {
return array(
0 => t('Text field'),
1 => t('Select box'),
2 => t('Radio buttons'),
3 => t('Checkboxes'),
);
}
function uc_attribute_priced_attributes($nid) {
$attributes = db_query("SELECT DISTINCT (pa.aid) FROM {uc_product_attributes} AS pa INNER JOIN {uc_attribute_options} AS ao ON ao.aid = pa.aid INNER JOIN {uc_product_options} AS po ON (po.oid = ao.oid AND po.nid = pa.nid) WHERE pa.nid = %d AND po.price <> 0 AND pa.display <> 0", $nid);
$aids = array();
while ($attribute = db_fetch_array($attributes)) {
$aids[] = $attribute['aid'];
}
return $aids;
}
function theme_uc_attribute_option($option, $price) {
$output = $option;
if ($price) {
$output .= ', ' . $price;
}
return $output;
}
function theme_uc_attribute_add_to_cart($form) {
$output = '<div class="attributes">';
$stripes = array(
'even' => 'odd',
'odd' => 'even',
);
$parity = 'even';
foreach (element_children($form) as $aid) {
$parity = $stripes[$parity];
$classes = array(
'attribute',
'attribute-' . $aid,
$parity,
);
$output .= '<div class="' . implode(' ', $classes) . '">';
$output .= drupal_render($form[$aid]);
$output .= '</div>';
}
$output .= drupal_render($form) . '</div>';
return $output;
}
function _uc_attribute_get_name($attribute, $title = TRUE) {
if (!$title && $attribute->label == '<none>') {
return NULL;
}
else {
return empty($attribute->label) || $attribute->label == '<none>' && $title ? $attribute->name : $attribute->label;
}
}