Parent Directory
|
Revision Log
|
Revision Graph
Begin the Ubercart 6.x-2.x branch.
| 1 | <?php |
| 2 | // $Id$ |
| 3 | |
| 4 | /** |
| 5 | * @file |
| 6 | * Übercart Attribute module. |
| 7 | * |
| 8 | * Allows customers to buy slightly different products from the same listing. |
| 9 | * |
| 10 | * Many manufacturers provide options to their products. This module provides a way |
| 11 | * for store administrators to consolidate these options into one product instead of |
| 12 | * listing each combination separately. This is accomplished through the use of Drupal's |
| 13 | * hook system. |
| 14 | * Coded by: Lyle Mantooth |
| 15 | */ |
| 16 | |
| 17 | /****************************************************************************** |
| 18 | * Drupal Hooks * |
| 19 | ******************************************************************************/ |
| 20 | |
| 21 | /** |
| 22 | * Implementation of hook_help(). |
| 23 | */ |
| 24 | function uc_attribute_help($path, $arg) { |
| 25 | switch ($path) { |
| 26 | // Help messages for the attributes overview on products and classes. |
| 27 | case 'node/%/edit/attributes': |
| 28 | 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'))); |
| 29 | case 'admin/store/products/classes/'. $arg[4] .'/attributes': |
| 30 | 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'))); |
| 31 | |
| 32 | // Help message for adding an attribute to a product or class. |
| 33 | case 'node/%/edit/attributes/add': |
| 34 | case 'admin/store/products/classes/'. $arg[4] .'/attributes/add': |
| 35 | return t('Select the attributes you want to add and submit the form.'); |
| 36 | |
| 37 | // Help message for adjusting the options on a product or class. |
| 38 | case 'node/%/edit/options': |
| 39 | case 'admin/store/products/classes/'. $arg[4] .'/options': |
| 40 | return t('Use the checkboxes to enable options for attributes and the radio buttons to specify defaults for the enabled options. Use the other fields to override the default settings for each option. Attributes with no enabled options will be displayed as text fields.'); |
| 41 | |
| 42 | // Help message for the product Adjustments tab. |
| 43 | case 'node/%/edit/adjustments': |
| 44 | 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.'); |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | /** |
| 49 | * Implementation of hook_menu(). |
| 50 | */ |
| 51 | function uc_attribute_menu() { |
| 52 | $items['admin/store/attributes'] = array( |
| 53 | 'title' => 'Attributes', |
| 54 | 'description' => 'Create and edit attributes and options.', |
| 55 | 'page callback' => 'uc_attribute_admin', |
| 56 | 'access arguments' => array('administer products'), |
| 57 | 'type' => MENU_NORMAL_ITEM, |
| 58 | 'weight' => -1, |
| 59 | ); |
| 60 | $items['admin/store/attributes/overview'] = array( |
| 61 | 'title' => 'Overview', |
| 62 | 'type' => MENU_DEFAULT_LOCAL_TASK, |
| 63 | 'weight' => 0, |
| 64 | ); |
| 65 | $items['admin/store/attributes/add'] = array( |
| 66 | 'title' => 'Add an attribute', |
| 67 | 'page callback' => 'drupal_get_form', |
| 68 | 'page arguments' => array('uc_attribute_form'), |
| 69 | 'access arguments' => array('administer products'), |
| 70 | 'type' => MENU_LOCAL_TASK, |
| 71 | 'weight' => 5, |
| 72 | ); |
| 73 | $items['admin/store/settings/attributes'] = array( |
| 74 | 'title' => 'Attribute settings', |
| 75 | 'description' => 'Configure the attribute settings', |
| 76 | 'page callback' => 'drupal_get_form', |
| 77 | 'page arguments' => array('uc_attribute_admin_settings'), |
| 78 | 'access arguments' => array('administer products'), |
| 79 | 'type' => MENU_NORMAL_ITEM, |
| 80 | ); |
| 81 | $items['admin/store/attributes/%uc_attribute/edit'] = array( |
| 82 | 'title' => 'Edit attribute', |
| 83 | 'page callback' => 'drupal_get_form', |
| 84 | 'page arguments' => array('uc_attribute_form', 3), |
| 85 | 'access arguments' => array('administer products'), |
| 86 | 'type' => MENU_CALLBACK, |
| 87 | ); |
| 88 | $items['admin/store/attributes/%uc_attribute/delete'] = array( |
| 89 | 'page callback' => 'drupal_get_form', |
| 90 | 'page arguments' => array('uc_attribute_delete_confirm', 3), |
| 91 | 'access arguments' => array('administer products'), |
| 92 | 'type' => MENU_CALLBACK, |
| 93 | ); |
| 94 | $items['admin/store/attributes/%uc_attribute/options'] = array( |
| 95 | 'title' => 'Options', |
| 96 | 'page callback' => 'uc_attribute_options', |
| 97 | 'page arguments' => array(3), |
| 98 | 'access arguments' => array('administer products'), |
| 99 | 'type' => MENU_CALLBACK, |
| 100 | ); |
| 101 | $items['admin/store/attributes/%uc_attribute/options/overview'] = array( |
| 102 | 'title' => 'Overview', |
| 103 | 'type' => MENU_DEFAULT_LOCAL_TASK, |
| 104 | 'weight' => 0, |
| 105 | ); |
| 106 | $items['admin/store/attributes/%uc_attribute/options/add'] = array( |
| 107 | 'title' => 'Add an option', |
| 108 | 'page callback' => 'drupal_get_form', |
| 109 | 'page arguments' => array('uc_attribute_option_form', 3, NULL), |
| 110 | 'access arguments' => array('administer products'), |
| 111 | 'type' => MENU_LOCAL_TASK, |
| 112 | 'weight' => 5, |
| 113 | ); |
| 114 | $items['admin/store/attributes/%uc_attribute/options/%uc_attribute_option/edit'] = array( |
| 115 | 'title' => 'Edit option', |
| 116 | 'page callback' => 'drupal_get_form', |
| 117 | 'page arguments' => array('uc_attribute_option_form', 3, 5), |
| 118 | 'access arguments' => array('administer products'), |
| 119 | 'type' => MENU_CALLBACK, |
| 120 | ); |
| 121 | $items['admin/store/attributes/%uc_attribute/options/%uc_attribute_option/delete'] = array( |
| 122 | 'title' => 'Delete option', |
| 123 | 'page callback' => 'drupal_get_form', |
| 124 | 'page arguments' => array('uc_attribute_option_delete_confirm', 3, 5), |
| 125 | 'access arguments' => array('administer products'), |
| 126 | 'type' => MENU_CALLBACK, |
| 127 | ); |
| 128 | |
| 129 | // Menu items for default product class attributes and options. |
| 130 | $items['admin/store/products/classes/%uc_product_class/attributes'] = array( |
| 131 | 'title' => 'Attributes', |
| 132 | 'page callback' => 'drupal_get_form', |
| 133 | 'page arguments' => array('uc_object_attributes_form', 4, 'class'), |
| 134 | 'access arguments' => array('administer product classes'), |
| 135 | 'type' => MENU_LOCAL_TASK, |
| 136 | 'weight' => 1, |
| 137 | ); |
| 138 | $items['admin/store/products/classes/%uc_product_class/options'] = array( |
| 139 | 'title' => 'Options', |
| 140 | 'page callback' => 'drupal_get_form', |
| 141 | 'page arguments' => array('uc_object_options_form', 4, 'class'), |
| 142 | 'access arguments' => array('administer product classes'), |
| 143 | 'type' => MENU_LOCAL_TASK, |
| 144 | 'weight' => 2, |
| 145 | ); |
| 146 | |
| 147 | // Insert subitems into the edit node page for product types. |
| 148 | $items['node/%node/edit/attributes'] = array( |
| 149 | 'title' => 'Attributes', |
| 150 | 'page callback' => 'drupal_get_form', |
| 151 | 'page arguments' => array('uc_object_attributes_form', 1, 'product', 'overview'), |
| 152 | 'access callback' => 'uc_product_is_product', |
| 153 | 'access arguments' => array(1), |
| 154 | 'type' => MENU_LOCAL_TASK, |
| 155 | 'weight' => 1, |
| 156 | ); |
| 157 | $items['node/%node/edit/attributes/add'] = array( |
| 158 | 'title' => 'Attributes', |
| 159 | 'page callback' => 'drupal_get_form', |
| 160 | 'page arguments' => array('uc_object_attributes_form', 1, 'product', 'add'), |
| 161 | 'access callback' => 'uc_product_is_product', |
| 162 | 'access arguments' => array(1), |
| 163 | 'type' => MENU_LOCAL_TASK, |
| 164 | 'weight' => 1, |
| 165 | ); |
| 166 | $items['node/%node/edit/options'] = array( |
| 167 | 'title' => 'Options', |
| 168 | 'page callback' => 'drupal_get_form', |
| 169 | 'page arguments' => array('uc_object_options_form', 1, 'product'), |
| 170 | 'access callback' => 'uc_product_is_product', |
| 171 | 'access arguments' => array(1), |
| 172 | 'type' => MENU_LOCAL_TASK, |
| 173 | 'weight' => 2, |
| 174 | ); |
| 175 | $items['node/%node/edit/adjustments'] = array( |
| 176 | 'title' => 'Adjustments', |
| 177 | 'page callback' => 'drupal_get_form', |
| 178 | 'page arguments' => array('uc_product_adjustments_form', 1), |
| 179 | 'access callback' => 'uc_product_is_product', |
| 180 | 'access arguments' => array(1), |
| 181 | 'type' => MENU_LOCAL_TASK, |
| 182 | 'weight' => 3, |
| 183 | ); |
| 184 | |
| 185 | return $items; |
| 186 | } |
| 187 | |
| 188 | function uc_attribute_init() { |
| 189 | drupal_add_css(drupal_get_path('module', 'uc_attribute') .'/uc_attribute.css'); |
| 190 | } |
| 191 | |
| 192 | function uc_attribute_theme() { |
| 193 | return array( |
| 194 | 'uc_object_attributes_form' => array( |
| 195 | 'arguments' => array('form' => NULL), |
| 196 | ), |
| 197 | 'uc_object_options_form' => array( |
| 198 | 'arguments' => array('form' => NULL), |
| 199 | ), |
| 200 | 'uc_attribute' => array( |
| 201 | 'arguments' => array('type' => NULL, 'data' => NULL, 'nid' => NULL), |
| 202 | ), |
| 203 | 'uc_attribute_options' => array( |
| 204 | 'arguments' => array('aid' => NULL, 'oid' => NULL), |
| 205 | ), |
| 206 | ); |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * Implementation of hook_form_alter(). |
| 211 | * |
| 212 | * Attach option selectors to the form with the "Add to Cart" button. |
| 213 | */ |
| 214 | function uc_attribute_form_alter(&$form, &$form_state, $form_id) { |
| 215 | if (strpos($form_id, 'add_to_cart_form') || strpos($form_id, 'add_product_form')) { |
| 216 | // If the node has a product list, add attributes to them |
| 217 | if (count(element_children($form['products']))) { |
| 218 | foreach (element_children($form['products']) as $key) { |
| 219 | $form['products'][$key] = _uc_attribute_alter_form($form['products'][$key]); |
| 220 | if (isset($form['products'][$key]['attributes'])) { |
| 221 | $form['products'][$key]['attributes']['#tree'] = true; |
| 222 | $form['products'][$key]['#type'] = 'fieldset'; |
| 223 | } |
| 224 | } |
| 225 | } |
| 226 | // If not, add attributes to the node. |
| 227 | else { |
| 228 | $form['attributes'] = array('#tree' => true, '#weight' => -1); |
| 229 | $form = _uc_attribute_alter_form($form); |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | /** |
| 235 | * Implementation of hook_nodeapi(). |
| 236 | */ |
| 237 | function uc_attribute_nodeapi(&$node, $op, $arg3 = null, $arg4 = null) { |
| 238 | if (in_array($node->type, module_invoke_all('product_types'))) { |
| 239 | switch ($op) { |
| 240 | case 'insert': |
| 241 | switch ($GLOBALS['db_type']) { |
| 242 | case 'mysqli': |
| 243 | case 'mysql': |
| 244 | db_query("INSERT IGNORE INTO {uc_product_attributes} (nid, aid, ordering, required, display, default_option) SELECT %d, aid, ordering, required, display, default_option FROM {uc_class_attributes} WHERE pcid = '%s'", $node->nid, $node->type); |
| 245 | 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); |
| 246 | break; |
| 247 | case 'pgsql': |
| 248 | db_query("INSERT INTO {uc_product_attributes} (nid, aid, ordering, required, display, default_option) SELECT %d, aid, ordering, required, display, default_option FROM {uc_class_attributes} WHERE pcid = '%s'", $node->nid, $node->type); |
| 249 | 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); |
| 250 | break; |
| 251 | } |
| 252 | |
| 253 | break; |
| 254 | case 'delete': |
| 255 | db_query("DELETE FROM {uc_product_options} WHERE nid = %d", $node->nid); |
| 256 | db_query("DELETE FROM {uc_product_adjustments} WHERE nid = %d", $node->nid); |
| 257 | db_query("DELETE FROM {uc_product_attributes} WHERE nid = %d", $node->nid); |
| 258 | break; |
| 259 | case 'update index': |
| 260 | $output = ''; |
| 261 | $attributes = uc_product_get_attributes($node->nid); |
| 262 | foreach ($attributes as $attribute) { |
| 263 | $output .= '<h3>'. $attribute->name .'</h3>'; |
| 264 | foreach ($attribute->options as $option) { |
| 265 | $output .= $option->name .' '; |
| 266 | } |
| 267 | $output .= "\n"; |
| 268 | } |
| 269 | $result = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = %d", $node->nid); |
| 270 | while ($adjustment = db_fetch_object($result)) { |
| 271 | $output .= '<h2>'. $adjustment->model ."<h2>\n"; |
| 272 | } |
| 273 | return $output; |
| 274 | } |
| 275 | } |
| 276 | } |
| 277 | |
| 278 | /****************************************************************************** |
| 279 | * Ubercart Hooks * |
| 280 | ******************************************************************************/ |
| 281 | |
| 282 | /** |
| 283 | * Stores the customer's choices in the cart. |
| 284 | */ |
| 285 | function uc_attribute_add_to_cart_data($form_state) { |
| 286 | $combination = array(); |
| 287 | if (!isset($form_state['values']['attributes'])) { |
| 288 | return array('attributes' => array(), 'model' => null); |
| 289 | } |
| 290 | foreach ($form_state['values']['attributes'] as $aid => $value) { |
| 291 | if (is_numeric($value)) { |
| 292 | $combination[$aid] = $value; |
| 293 | } |
| 294 | } |
| 295 | $result = db_query("SELECT model FROM {uc_product_adjustments} WHERE nid = %d AND combination LIKE '%s'", $form_state['values']['nid'], serialize($combination)); |
| 296 | $model = db_result($result); |
| 297 | // drupal_set_message('Attributes to add to order Array(aid => oid):<pre>'. print_r($form_state['values']['attributes'], true) . $model .'</pre>'); |
| 298 | // Preserve the 'attributes' key to allow other modules to add to the data field. |
| 299 | return array('attributes' => $form_state['values']['attributes'], 'model' => $model); |
| 300 | } |
| 301 | |
| 302 | /** |
| 303 | * Implementation of hook_product_class(). |
| 304 | */ |
| 305 | function uc_attribute_product_class($type, $op) { |
| 306 | switch ($op) { |
| 307 | case 'delete': |
| 308 | db_query("DELETE FROM {uc_class_attributes} WHERE pcid = '%s'", $type); |
| 309 | db_query("DELETE FROM {uc_class_attribute_options} WHERE pcid = '%s'", $type); |
| 310 | break; |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | /** |
| 315 | * Implementation of hook_cart_item(). |
| 316 | */ |
| 317 | function uc_attribute_cart_item($op, &$item) { |
| 318 | switch ($op) { |
| 319 | case 'load': |
| 320 | $item->options = _uc_cart_product_get_options($item); |
| 321 | $op_costs = 0; |
| 322 | $op_prices = 0; |
| 323 | $op_weight = 0; |
| 324 | foreach ($item->options as $option) { |
| 325 | $op_costs += $option['cost']; |
| 326 | $op_prices += $option['price']; |
| 327 | $op_weight += $option['weight']; |
| 328 | } |
| 329 | $item->cost += $op_costs; |
| 330 | $item->price += $op_prices; |
| 331 | $item->weight += $op_weight; |
| 332 | if (!empty($item->data['model'])) { |
| 333 | $item->model = $item->data['model']; |
| 334 | } |
| 335 | break; |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | /****************************************************************************** |
| 340 | * Menu Callbacks * |
| 341 | ******************************************************************************/ |
| 342 | |
| 343 | /** |
| 344 | * Change the display of attribute option prices. |
| 345 | * |
| 346 | * @ingroup forms |
| 347 | */ |
| 348 | function uc_attribute_admin_settings() { |
| 349 | $form = array(); |
| 350 | |
| 351 | $form['uc_attribute_option_price_format'] = array('#type' => 'radios', |
| 352 | '#title' => t('Option price format'), |
| 353 | '#default_value' => variable_get('uc_attribute_option_price_format', 'adjustment'), |
| 354 | '#options' => array('none' => t('Do not display'), |
| 355 | 'adjustment' => t('Display price adjustment'), |
| 356 | 'total' => t('Display total price'), |
| 357 | ), |
| 358 | '#description' => t('Formats the price in the attribute selection form when the customer adds a product to their cart. The total price will only be displayed on products with only one price affecting attribute.'), |
| 359 | ); |
| 360 | |
| 361 | return system_settings_form($form); |
| 362 | } |
| 363 | |
| 364 | // Displays a paged list and overview of existing product attributes. |
| 365 | function uc_attribute_admin() { |
| 366 | $header = array( |
| 367 | array('data' => t('Name'), 'field' => 'a.name', 'sort' => 'asc'), |
| 368 | t('Required'), |
| 369 | array('data' => t('Order'), 'field' => 'a.ordering'), |
| 370 | t('Number of options'), |
| 371 | t('Display type'), |
| 372 | t('Operations'), |
| 373 | ); |
| 374 | |
| 375 | $display_types = _uc_attribute_display_types(); |
| 376 | |
| 377 | $result = pager_query("SELECT a.*, COUNT(ao.oid) AS options FROM {uc_attributes} AS a LEFT JOIN {uc_attribute_options} AS ao ON a.aid = ao.aid GROUP BY a.aid, a.name, a.ordering". tablesort_sql($header), 30, 0, "SELECT COUNT(aid) FROM {uc_attributes}"); |
| 378 | while ($attr = db_fetch_object($result)) { |
| 379 | $ops = array( |
| 380 | l(t('edit'), 'admin/store/attributes/'. $attr->aid .'/edit'), |
| 381 | l(t('options'), 'admin/store/attributes/'. $attr->aid .'/options'), |
| 382 | l(t('delete'), 'admin/store/attributes/'. $attr->aid .'/delete'), |
| 383 | ); |
| 384 | $rows[] = array( |
| 385 | $attr->name, |
| 386 | $attr->required == 1 ? t('Yes') : t('No'), |
| 387 | array('data' => $attr->ordering, 'align' => 'center'), |
| 388 | array('data' => $attr->options, 'align' => 'center'), |
| 389 | $display_types[$attr->display], |
| 390 | implode(' ', $ops), |
| 391 | ); |
| 392 | } |
| 393 | |
| 394 | if (count($rows) == 0) { |
| 395 | $rows[] = array( |
| 396 | array('data' => t('No product attributes have been added yet.'), 'colspan' => '6') |
| 397 | ); |
| 398 | } |
| 399 | |
| 400 | $output = theme('table', $header, $rows) . theme('pager', NULL, 30) |
| 401 | . l(t('Add an attribute'), 'admin/store/attributes/add'); |
| 402 | |
| 403 | return $output; |
| 404 | } |
| 405 | |
| 406 | /** |
| 407 | * Form builder for product attributes. |
| 408 | * |
| 409 | * @ingroup forms |
| 410 | * @see uc_attribute_form_validate |
| 411 | * @see uc_attribute_form_submit |
| 412 | */ |
| 413 | function uc_attribute_form($form_state, $attribute = NULL) { |
| 414 | // If an attribute specified, add its ID as a hidden value. |
| 415 | |
| 416 | if (!empty($attribute)) { |
| 417 | $form['aid'] = array('#type' => 'hidden', '#value' => $attribute->aid); |
| 418 | drupal_set_title(t('Edit attribute: %name', array('%name' => $attribute->name))); |
| 419 | } |
| 420 | |
| 421 | $form['name'] = array( |
| 422 | '#type' => 'textfield', |
| 423 | '#title' => t('Name'), |
| 424 | '#description' => t('This name will appear to customers on product add to cart forms.'), |
| 425 | '#default_value' => $attribute->name, |
| 426 | '#required' => TRUE, |
| 427 | ); |
| 428 | $form['description'] = array( |
| 429 | '#type' => 'textfield', |
| 430 | '#title' => t('Help text'), |
| 431 | '#description' => t('<b>Optional.</b> Enter the help text that will display beneath the attribute on product add to cart forms.'), |
| 432 | '#default_value' => $attribute->description, |
| 433 | '#maxlength' => 255, |
| 434 | ); |
| 435 | $form['required'] = array( |
| 436 | '#type' => 'checkbox', |
| 437 | '#title' => t('Make this attribute required, forcing the customer to choose an option.'), |
| 438 | '#description' => t('Selecting this for an attribute will disregard any default option you specify.<br />May be overridden at the product level.'), |
| 439 | '#default_value' => $attribute->required, |
| 440 | ); |
| 441 | $form['display'] = array( |
| 442 | '#type' => 'select', |
| 443 | '#title' => t('Display type'), |
| 444 | '#description' => t('This specifies how the options for this attribute will be presented.<br />May be overridden at the product level.'), |
| 445 | '#options' => _uc_attribute_display_types(), |
| 446 | '#default_value' => isset($attribute->display) ? $attribute->display : 1, |
| 447 | ); |
| 448 | $form['ordering'] = array( |
| 449 | '#type' => 'weight', |
| 450 | '#title' => t('Order'), |
| 451 | '#description' => t('Multiple attributes on an add to cart form are sorted by this value and then by their name.<br />May be overridden at the product level.'), |
| 452 | '#default_value' => isset($attribute->ordering) ? $attribute->ordering : 0, |
| 453 | ); |
| 454 | |
| 455 | $form['submit'] = array( |
| 456 | '#type' => 'submit', |
| 457 | '#value' => t('Submit'), |
| 458 | '#suffix' => l(t('Cancel'), 'admin/store/attributes'), |
| 459 | ); |
| 460 | |
| 461 | return $form; |
| 462 | } |
| 463 | |
| 464 | /** |
| 465 | * Submit function for uc_attribute_add_form(). |
| 466 | */ |
| 467 | function uc_attribute_form_submit($form, &$form_state) { |
| 468 | if (!empty($form_state['values']['aid'])) { |
| 469 | db_query("UPDATE {uc_attributes} SET name = '%s', ordering = %d, required = %d, display = %d, description = '%s' WHERE aid = %d", $form_state['values']['name'], $form_state['values']['ordering'], $form_state['values']['required'], $form_state['values']['display'], $form_state['values']['description'], $form_state['values']['aid']); |
| 470 | } |
| 471 | else { |
| 472 | db_query("INSERT INTO {uc_attributes} (name, ordering, required, display, description) VALUES ('%s', %d, %d, %d, '%s')", $form_state['values']['name'], $form_state['values']['ordering'], $form_state['values']['required'], $form_state['values']['display'], $form_state['values']['description']); |
| 473 | } |
| 474 | |
| 475 | $form_state['redirect'] = 'admin/store/attributes'; |
| 476 | } |
| 477 | |
| 478 | // Confirms the deletion of the given attribute. |
| 479 | function uc_attribute_delete_confirm($form_state, $attribute) { |
| 480 | // If we got a bunk attribute, kick out an error message. |
| 481 | if (empty($attribute)) { |
| 482 | drupal_set_message(t('There is no attribute with that ID.'), 'error'); |
| 483 | drupal_goto('admin/store/attributes'); |
| 484 | } |
| 485 | |
| 486 | $form['aid'] = array('#type' => 'value', '#value' => $attribute->aid); |
| 487 | $form['#redirect'] = 'admin/store/attributes'; |
| 488 | |
| 489 | $count = db_result(db_query("SELECT COUNT(*) FROM {uc_product_attributes} WHERE aid = %d", $attribute->aid)); |
| 490 | |
| 491 | $output = confirm_form($form, t('Are you sure you want to delete the attribute %name?', array('%name' => $attribute->name)), |
| 492 | 'admin/store/attributes', format_plural($count, 'There is @count product with this attribute.', 'There are @count products with this attribute.'), |
| 493 | t('Delete'), t('Cancel')); |
| 494 | |
| 495 | return $output; |
| 496 | } |
| 497 | |
| 498 | function uc_attribute_delete_confirm_submit($form_id, &$form_state) { |
| 499 | if ($form_state['values']['confirm']) { |
| 500 | db_query("DELETE FROM co USING {uc_class_attribute_options} AS co, {uc_attribute_options} AS ao WHERE co.oid = ao.oid AND ao.aid = %d", $form_state['values']['aid']); |
| 501 | db_query("DELETE FROM {uc_class_attributes} WHERE aid = %d", $form_state['values']['aid']); |
| 502 | db_query("DELETE FROM po USING {uc_product_options} AS po, {uc_attribute_options} AS ao WHERE po.oid = ao.oid AND ao.aid = %d", $form_state['values']['aid']); |
| 503 | db_query("DELETE FROM pd USING {uc_product_adjustments} AS pd, {uc_product_attributes} AS pa WHERE pd.nid = pa.nid AND pa.aid = %d", $form_state['values']['aid']); |
| 504 | db_query("DELETE FROM {uc_product_attributes} WHERE aid = %d", $form_state['values']['aid']); |
| 505 | db_query("DELETE FROM {uc_attribute_options} WHERE aid = %d", $form_state['values']['aid']); |
| 506 | db_query("DELETE FROM {uc_attributes} WHERE aid = %d", $form_state['values']['aid']); |
| 507 | drupal_set_message(t('Product attribute deleted.')); |
| 508 | } |
| 509 | } |
| 510 | |
| 511 | // Display options and the modifications to products they represent. |
| 512 | function uc_attribute_options($attribute) { |
| 513 | // If we got a bunk attribute, kick out an error message. |
| 514 | if (empty($attribute)) { |
| 515 | drupal_set_message(t('There is no attribute with that ID.'), 'error'); |
| 516 | drupal_goto('admin/store/attributes'); |
| 517 | } |
| 518 | $aid = $attribute->aid; |
| 519 | |
| 520 | drupal_set_title(t('Options for %name', array('%name' => $attribute->name))); |
| 521 | |
| 522 | $header = array(t('Name'), t('Default cost'), t('Default price'), t('Default weight'), t('Order'), t('Operations')); |
| 523 | |
| 524 | foreach ($attribute->options as $key => $data) { |
| 525 | $ops = array( |
| 526 | l(t('edit'), 'admin/store/attributes/'. $aid .'/options/'. $key .'/edit'), |
| 527 | l(t('delete'), 'admin/store/attributes/'. $aid .'/options/'. $key .'/delete'), |
| 528 | ); |
| 529 | $rows[] = array($data->name, $data->cost, $data->price, $data->weight, $data->ordering, implode(' ', $ops)); |
| 530 | } |
| 531 | if (count($rows) == 0) { |
| 532 | $rows[] = array( |
| 533 | array('data' => t('No options for this attribute have been added yet.'), 'colspan' => '6') |
| 534 | ); |
| 535 | } |
| 536 | |
| 537 | $output .= theme('table', $header, $rows) |
| 538 | . l(t('Add an option'), 'admin/store/attributes/'. $aid .'/options/add'); |
| 539 | |
| 540 | return $output; |
| 541 | } |
| 542 | |
| 543 | /** |
| 544 | * Form builder for attribute options. |
| 545 | * |
| 546 | * @ingroup forms |
| 547 | * @see uc_attribute_option_form_validate |
| 548 | * @see uc_attribute_option_form_submit |
| 549 | */ |
| 550 | function uc_attribute_option_form($form_state, $attribute, $option = NULL) { |
| 551 | // If we got a bunk attribute, kick out an error message. |
| 552 | if (empty($attribute)) { |
| 553 | drupal_set_message(t('There is no attribute with that ID.'), 'error'); |
| 554 | drupal_goto('admin/store/attributes'); |
| 555 | } |
| 556 | $aid = $attribute->aid; |
| 557 | |
| 558 | $form['aid'] = array('#type' => 'hidden', '#value' => $aid); |
| 559 | |
| 560 | if (!empty($option)) { |
| 561 | $form['oid'] = array('#type' => 'hidden', '#value' => $option->oid); |
| 562 | drupal_set_title(t('Edit option: %name', array('%name' => $option->name))); |
| 563 | } |
| 564 | else { |
| 565 | drupal_set_title(t('Options for %name', array('%name' => $attribute->name))); |
| 566 | } |
| 567 | |
| 568 | $form['name'] = array( |
| 569 | '#type' => 'textfield', |
| 570 | '#title' => t('Name'), |
| 571 | '#description' => t('This name will appear to customers on product add to cart forms.'), |
| 572 | '#default_value' => $option->name, |
| 573 | '#required' => TRUE, |
| 574 | '#weight' => 0, |
| 575 | ); |
| 576 | $form['ordering'] = array( |
| 577 | '#type' => 'weight', |
| 578 | '#title' => t('Order'), |
| 579 | '#description' => t('Options will be listed sorted by this value and then by their name.<br />May be overridden at the product level.'), |
| 580 | '#default_value' => isset($option->ordering) ? $option->ordering : 0, |
| 581 | '#weight' => 4, |
| 582 | ); |
| 583 | $form['adjustments'] = array( |
| 584 | '#type' => 'fieldset', |
| 585 | '#title' => t('Default adjustments'), |
| 586 | '#description' => t('Enter a positive or negative value for each adjustment applied when this option is selected.<br />Any of these may be overriden at the product level.'), |
| 587 | '#collapsible' => FALSE, |
| 588 | '#weight' => 8, |
| 589 | ); |
| 590 | $form['adjustments']['cost'] = array( |
| 591 | '#type' => 'textfield', |
| 592 | '#title' => t('Cost'), |
| 593 | '#default_value' => $option->cost, |
| 594 | '#weight' => 1, |
| 595 | ); |
| 596 | $form['adjustments']['price'] = array( |
| 597 | '#type' => 'textfield', |
| 598 | '#title' => t('Price'), |
| 599 | '#default_value' => $option->price, |
| 600 | '#weight' => 2, |
| 601 | ); |
| 602 | $form['adjustments']['weight'] = array( |
| 603 | '#type' => 'textfield', |
| 604 | '#title' => t('Weight'), |
| 605 | '#default_value' => $option->weight, |
| 606 | '#weight' => 3, |
| 607 | ); |
| 608 | |
| 609 | $form['submit'] = array( |
| 610 | '#type' => 'submit', |
| 611 | '#value' => t('Submit'), |
| 612 | '#suffix' => l(t('Cancel'), 'admin/store/attributes/'. $aid .'/options'), |
| 613 | '#weight' => 10, |
| 614 | ); |
| 615 | |
| 616 | return $form; |
| 617 | } |
| 618 | |
| 619 | /** |
| 620 | * Validate number formats. |
| 621 | */ |
| 622 | function uc_attribute_option_form_validate($form, &$form_state) { |
| 623 | $pattern = '/^-?\d*(\.\d*)?$/'; |
| 624 | $price_error = t('This must be in a valid number format. No commas and only one decimal point.'); |
| 625 | if (!is_numeric($form_state['values']['cost']['#value']) && !preg_match($pattern, $form_state['values']['cost']['#value'])) { |
| 626 | form_set_error('cost', $price_error); |
| 627 | } |
| 628 | if (!is_numeric($form_state['values']['price']['#value']) && !preg_match($pattern, $form_state['values']['price']['#value'])) { |
| 629 | form_set_error('price', $price_error); |
| 630 | } |
| 631 | if (!is_numeric($form_state['values']['weight']['#value']) && !preg_match($pattern, $form_state['values']['weight']['#value'])) { |
| 632 | form_set_error('weight', $price_error); |
| 633 | } |
| 634 | } |
| 635 | |
| 636 | /** |
| 637 | * Submit function for uc_attribute_option_form(). |
| 638 | */ |
| 639 | function uc_attribute_option_form_submit($form, &$form_state) { |
| 640 | if (!isset($form_state['values']['oid'])) { |
| 641 | db_query("INSERT INTO {uc_attribute_options} (aid, name, cost, price, weight, ordering) VALUES (%d, '%s', %f, %f, %f, %d)", |
| 642 | $form_state['values']['aid'], $form_state['values']['name'], $form_state['values']['cost'], $form_state['values']['price'], $form_state['values']['weight'], $form_state['values']['ordering']); |
| 643 | } |
| 644 | else { |
| 645 | db_query("UPDATE {uc_attribute_options} SET name = '%s', cost = %f, price = %f, weight = %f, ordering = %d WHERE aid = %d AND oid = %d", |
| 646 | $form_state['values']['name'], $form_state['values']['cost'], $form_state['values']['price'], $form_state['values']['weight'], $form_state['values']['ordering'], $form_state['values']['aid'], $form_state['values']['oid']); |
| 647 | } |
| 648 | $form_state['redirect'] = 'admin/store/attributes/'. $form_state['values']['aid'] .'/options'; |
| 649 | } |
| 650 | |
| 651 | // Confirms deletion of the given attribute option. |
| 652 | function uc_attribute_option_delete_confirm($form_state, $attribute, $option) { |
| 653 | if (empty($option)) { |
| 654 | drupal_set_message(t('There is no option with that ID.'), 'error'); |
| 655 | drupal_goto('admin/store/attributes/'. $aid .'/options'); |
| 656 | } |
| 657 | $aid = $attribute->aid; |
| 658 | $oid = $option->oid; |
| 659 | |
| 660 | $form['aid'] = array('#type' => 'value', '#value' => $aid); |
| 661 | $form['oid'] = array('#type' => 'value', '#value' => $oid); |
| 662 | |
| 663 | $output = confirm_form($form, t('Are you sure you want to delete the option %name?', array('%name' => $option->name)), |
| 664 | 'admin/store/attributes/'. $aid .'/options', '', |
| 665 | t('Delete'), t('Cancel')); |
| 666 | |
| 667 | return $output; |
| 668 | } |
| 669 | |
| 670 | /** |
| 671 | * Submit function for uc_attribute_option_delete_confirm(). |
| 672 | */ |
| 673 | function uc_attribute_option_delete_confirm_submit($form, &$form_state) { |
| 674 | if ($form_state['values']['confirm']) { |
| 675 | $match = 'i:'. $form_state['values']['aid'] .';s:'. strlen($form_state['values']['oid']) .':"'. $form_state['values']['oid'] .'";'; |
| 676 | db_query("DELETE FROM {uc_product_adjustments} WHERE combination LIKE '%%%s%%'", $match); |
| 677 | db_query("DELETE ao, co, po FROM {uc_attribute_options} AS ao LEFT JOIN {uc_product_options} AS po ON ao.oid = po.oid LEFT JOIN {uc_class_attribute_options} AS co ON ao.oid = co.oid WHERE ao.oid = %d", $form_state['values']['oid']); |
| 678 | } |
| 679 | $form_state['redirect'] = 'admin/store/attributes/'. $form_state['values']['aid'] .'/options'; |
| 680 | } |
| 681 | |
| 682 | // Form to associate attributes with products or classes. |
| 683 | function uc_object_attributes_form($form_state, $object, $type, $view = 'overview') { |
| 684 | switch ($type) { |
| 685 | case 'class': |
| 686 | $class = $object; |
| 687 | $id = $class->pcid; |
| 688 | if (empty($class->name)) { |
| 689 | drupal_goto('admin/store/products/classes/'. $id); |
| 690 | } |
| 691 | drupal_set_title(check_plain($class->name)); |
| 692 | $attributes = uc_class_get_attributes($id); |
| 693 | break; |
| 694 | case 'product': |
| 695 | default: |
| 696 | $product = $object; |
| 697 | $id = $product->nid; |
| 698 | if (empty($product->title)) { |
| 699 | drupal_goto('node/'. $id); |
| 700 | } |
| 701 | drupal_set_title(check_plain($product->title)); |
| 702 | $attributes = uc_product_get_attributes($id); |
| 703 | } |
| 704 | |
| 705 | $used_aids = array(); |
| 706 | foreach ($attributes as $attribute) { |
| 707 | $used_aids[] = $attribute->aid; |
| 708 | } |
| 709 | |
| 710 | if ($view == 'overview') { |
| 711 | $form['#tree'] = TRUE; |
| 712 | |
| 713 | if (count($attributes) > 0) { |
| 714 | foreach ($attributes as $attribute) { |
| 715 | $option = $attribute->options[$attribute->default_option]; |
| 716 | |
| 717 | $form['attributes'][$attribute->aid] = array( |
| 718 | 'remove' => array( |
| 719 | '#type' => 'checkbox', |
| 720 | '#default_value' => 0, |
| 721 | ), |
| 722 | 'name' => array( |
| 723 | '#value' => $attribute->name, |
| 724 | ), |
| 725 | 'option' => array( |
| 726 | '#value' => $option ? ($option->name .' ('. uc_currency_format($option->price) .')' ) : t('n/a'), |
| 727 | ), |
| 728 | 'required' => array( |
| 729 | '#type' => 'checkbox', |
| 730 | '#default_value' => $attribute->required, |
| 731 | ), |
| 732 | 'ordering' => array( |
| 733 | '#type' => 'weight', |
| 734 | '#default_value' => $attribute->ordering, |
| 735 | ), |
| 736 | 'display' => array( |
| 737 | '#type' => 'select', |
| 738 | '#default_value' => $attribute->display, |
| 739 | '#options' => _uc_attribute_display_types(), |
| 740 | ), |
| 741 | ); |
| 742 | } |
| 743 | |
| 744 | $form['save'] = array( |
| 745 | '#type' => 'submit', |
| 746 | '#value' => t('Save changes'), |
| 747 | '#weight' => -2, |
| 748 | ); |
| 749 | } |
| 750 | } |
| 751 | else if ($view == 'add') { |
| 752 | // Get list of attributes not already assigned to this node or class. |
| 753 | $unused_attributes = array(); |
| 754 | $result = db_query("SELECT a.aid, a.name FROM {uc_attributes} AS a LEFT JOIN {uc_attribute_options} AS ao ON a.aid = ao.aid GROUP BY a.aid, a.name ORDER BY a.name"); |
| 755 | while ($attribute = db_fetch_object($result)) { |
| 756 | if (!in_array($attribute->aid, $used_aids)) { |
| 757 | $unused_attributes[$attribute->aid] = $attribute->name; |
| 758 | } |
| 759 | } |
| 760 | |
| 761 | $form['add_attributes'] = array( |
| 762 | '#type' => 'select', |
| 763 | '#title' => t('Attributes'), |
| 764 | '#description' => t('Hold Ctrl + click to select multiple attributes.'), |
| 765 | '#options' => count($unused_attributes) > 0 ? $unused_attributes : array(t('No attributes left to add.')), |
| 766 | '#disabled' => count($unused_attributes) == 0 ? TRUE : FALSE, |
| 767 | '#multiple' => TRUE, |
| 768 | '#weight' => -1 |
| 769 | ); |
| 770 | $form['add'] = array( |
| 771 | '#type' => 'submit', |
| 772 | '#value' => t('Add attributes'), |
| 773 | '#suffix' => l(t('Cancel'), $type == 'product' ? 'node/'. $id .'/edit/attributes' : 'admin/store/products/classes/'. $class->pcid .'/attributes'), |
| 774 | '#weight' => 0, |
| 775 | ); |
| 776 | } |
| 777 | |
| 778 | $form['id'] = array( |
| 779 | '#type' => 'value', |
| 780 | '#value' => $id, |
| 781 | ); |
| 782 | $form['type'] = array( |
| 783 | '#type' => 'value', |
| 784 | '#value' => $type, |
| 785 | ); |
| 786 | $form['view'] = array( |
| 787 | '#type' => 'value', |
| 788 | '#value' => $view, |
| 789 | ); |
| 790 | |
| 791 | return $form; |
| 792 | } |
| 793 | |
| 794 | /** |
| 795 | * Display the formatted attribute form. |
| 796 | * |
| 797 | * @ingroup themeable |
| 798 | */ |
| 799 | function theme_uc_object_attributes_form($form) { |
| 800 | if ($form['view']['#value'] == 'overview') { |
| 801 | $header = array(t('Remove'), t('Name'), t('Default'), t('Required'), t('Order'), t('Display')); |
| 802 | |
| 803 | if (count(element_children($form['attributes'])) > 0) { |
| 804 | foreach (element_children($form['attributes']) as $aid) { |
| 805 | $rows[] = array( |
| 806 | drupal_render($form['attributes'][$aid]['remove']), |
| 807 | drupal_render($form['attributes'][$aid]['name']), |
| 808 | drupal_render($form['attributes'][$aid]['option']), |
| 809 | drupal_render($form['attributes'][$aid]['required']), |
| 810 | drupal_render($form['attributes'][$aid]['ordering']), |
| 811 | drupal_render($form['attributes'][$aid]['display']), |
| 812 | ); |
| 813 | } |
| 814 | } |
| 815 | else { |
| 816 | $rows[] = array( |
| 817 | array('data' => t('You must first <a href="!url">add attributes to this !type</a>.', array('!url' => request_uri() .'/add', '!type' => $form['type']['#value'])), 'colspan' => 6), |
| 818 | ); |
| 819 | } |
| 820 | |
| 821 | $output = theme('table', $header, $rows); |
| 822 | } |
| 823 | |
| 824 | $output .= drupal_render($form); |
| 825 | |
| 826 | return $output; |
| 827 | } |
| 828 | |
| 829 | function uc_object_attributes_form_submit($form, &$form_state) { |
| 830 | if ($form_state['values']['type'] == 'product') { |
| 831 | $attr_table = '{uc_product_attributes}'; |
| 832 | $opt_table = '{uc_product_options}'; |
| 833 | $id = 'nid'; |
| 834 | $sql_type = '%d'; |
| 835 | } |
| 836 | else if ($form_state['values']['type'] == 'class') { |
| 837 | $attr_table = '{uc_class_attributes}'; |
| 838 | $opt_table = '{uc_class_attribute_options}'; |
| 839 | $id = 'pcid'; |
| 840 | $sql_type = "'%s'"; |
| 841 | } |
| 842 | |
| 843 | if ($form_state['values']['view'] == 'overview' && is_array($form_state['values']['attributes'])) { |
| 844 | foreach ($form_state['values']['attributes'] as $aid => $attribute) { |
| 845 | if ($attribute['remove']) { |
| 846 | $remove_aids[] = $aid; |
| 847 | } |
| 848 | else { |
| 849 | db_query("UPDATE $attr_table SET ordering = %d, required = %d, display = %d WHERE aid = %d AND $id = $sql_type", $attribute['ordering'], $attribute['required'], $attribute['display'], $aid, $form_state['values']['id']); |
| 850 | $changed = TRUE; |
| 851 | } |
| 852 | } |
| 853 | |
| 854 | if (count($remove_aids) > 0) { |
| 855 | $values = array($form_state['values']['id'], implode(', ', $remove_aids)); |
| 856 | |
| 857 | db_query("DELETE po FROM $opt_table AS po LEFT JOIN {uc_attribute_options} AS ao ON po.oid = ao.oid WHERE po.$id = $sql_type AND ao.aid IN (%s)", $values); |
| 858 | db_query("DELETE FROM $attr_table WHERE $id = $sql_type AND aid IN (%s)", $values); |
| 859 | if ($form_state['values']['type'] == 'product') { |
| 860 | db_query("DELETE FROM {uc_product_adjustments} WHERE nid = %d", $form_state['values']['id']); |
| 861 | } |
| 862 | |
| 863 | drupal_set_message(format_plural(count($remove_aids), '@count attribute has been removed.', '@count attributes have been removed.')); |
| 864 | } |
| 865 | |
| 866 | if ($changed) { |
| 867 | drupal_set_message(t('The changes have been saved.')); |
| 868 | } |
| 869 | } |
| 870 | else if ($form_state['values']['view'] == 'add') { |
| 871 | foreach ($form_state['values']['add_attributes'] as $aid) { |
| 872 | db_query("INSERT INTO $attr_table ($id, aid, ordering, default_option, required, display) SELECT $sql_type, aid, ordering, 0, required, display FROM {uc_attributes} WHERE aid = %d", $form_state['values']['id'], $aid); |
| 873 | } |
| 874 | if (count($form_state['values']['add_attributes']) > 0) { |
| 875 | if ($form_state['values']['type'] == 'product') { |
| 876 | db_query("DELETE FROM {uc_product_adjustments} WHERE nid = %d", $form_state['values']['id']); |
| 877 | } |
| 878 | drupal_set_message(format_plural(count($form_state['values']['add_attributes']), '@count attribute has been added.', '@count attributes have been added.')); |
| 879 | } |
| 880 | } |
| 881 | |
| 882 | if ($form_state['values']['type'] == 'product') { |
| 883 | $form_state['redirect'] = 'node/'. $form_state['values']['id'] .'/edit/attributes'; |
| 884 | } |
| 885 | else { |
| 886 | $form_state['redirect'] = 'admin/store/products/classes/'. $form_state['values']['id'] .'/attributes'; |
| 887 | } |
| 888 | } |
| 889 | |
| 890 | // Form to assign and modify attribute options on products or classes. |
| 891 | function uc_object_options_form($form_state, $object, $type) { |
| 892 | if ($type == 'product') { |
| 893 | $product = $object; |
| 894 | $id = $product->nid; |
| 895 | drupal_set_title(check_plain($product->title)); |
| 896 | $attributes = uc_product_get_attributes($id); |
| 897 | $table = '{uc_product_options}'; |
| 898 | $id_type = 'nid'; |
| 899 | $sql_type = '%d'; |
| 900 | } |
| 901 | else if ($type == 'class') { |
| 902 | $class = $object; |
| 903 | $id = $class->pcid; |
| 904 | drupal_set_title(check_plain($class->name)); |
| 905 | $attributes = uc_class_get_attributes($id); |
| 906 | $table = '{uc_class_attribute_options}'; |
| 907 | $id_type = 'pcid'; |
| 908 | $sql_type = "'%s'"; |
| 909 | } |
| 910 | |
| 911 | foreach ($attributes as $aid => $attribute) { |
| 912 | $form['attributes'][$aid] = array( |
| 913 | '#prefix' => '<tr>', |
| 914 | '#suffix' => '</tr>', |
| 915 | ); |
| 916 | $form['attributes'][$aid]['name'] = array( |
| 917 | '#value' => $attribute->name, |
| 918 | ); |
| 919 | $form['attributes'][$aid]['aid'] = array( |
| 920 | '#type' => 'hidden', |
| 921 | '#value' => $attribute->aid, |
| 922 | ); |
| 923 | $form['attributes'][$aid]['ordering'] = array( |
| 924 | '#type' => 'value', |
| 925 | '#value' => $attribute->ordering, |
| 926 | ); |
| 927 | |
| 928 | $form['attributes'][$aid]['options'] = array('#weight' => 2); |
| 929 | |
| 930 | $base_attr = uc_attribute_load($attribute->aid); |
| 931 | |
| 932 | if ($base_attr->options) { |
| 933 | $options = array(); |
| 934 | |
| 935 | $result = db_query("SELECT ao.aid, ao.oid, ao.name, ao.cost AS default_cost, ao.price AS default_price, ao.weight AS default_weight, ao.ordering AS default_ordering, po.cost, po.price, po.weight, po.ordering FROM {uc_attribute_options} AS ao LEFT JOIN $table AS po ON ao.oid = po.oid AND po.$id_type = $sql_type WHERE aid = %d ORDER BY po.ordering, default_ordering, ao.name", $id, $attribute->aid); |
| 936 | while ($option = db_fetch_object($result)) { |
| 937 | $oid = $option->oid; |
| 938 | $options[$oid] = ''; |
| 939 | |
| 940 | $form['attributes'][$aid]['options'][$oid]['select'] = array( |
| 941 | '#type' => 'checkbox', |
| 942 | '#default_value' => isset($attribute->options[$oid]) ? TRUE : FALSE, |
| 943 | '#title' => $option->name, |
| 944 | ); |
| 945 | $form['attributes'][$aid]['options'][$oid]['cost'] = array( |
| 946 | '#type' => 'textfield', |
| 947 | '#default_value' => is_null($option->cost) ? $option->default_cost : $option->cost, |
| 948 | '#size' => 6, |
| 949 | ); |
| 950 | $form['attributes'][$aid]['options'][$oid]['price'] = array( |
| 951 | '#type' => 'textfield', |
| 952 | '#default_value' => is_null($option->price) ? $option->default_price : $option->price, |
| 953 | '#size' => 6, |
| 954 | ); |
| 955 | $form['attributes'][$aid]['options'][$oid]['weight'] = array( |
| 956 | '#type' => 'textfield', |
| 957 | '#default_value' => is_null($option->weight) ? $option->default_weight : $option->weight, |
| 958 | '#size' => 5, |
| 959 | ); |
| 960 | $form['attributes'][$aid]['options'][$oid]['ordering'] = array( |
| 961 | '#type' => 'weight', |
| 962 | '#default_value' => is_null($option->ordering) ? $option->default_ordering : $option->ordering, |
| 963 | ); |
| 964 | } |
| 965 | |
| 966 | $form['attributes'][$aid]['default'] = array( |
| 967 | '#type' => 'radios', |
| 968 | '#options' => $options, |
| 969 | '#default_value' => /* $attribute->required ? NULL : */ $attribute->default_option, |
| 970 | //'#disabled' => $attribute->required, |
| 971 | ); |
| 972 | } |
| 973 | else { |
| 974 | $form['attributes'][$aid]['default'] = array( |
| 975 | '#value' => t('This attribute does not have any options.'), |
| 976 | ); |
| 977 | } |
| 978 | } |
| 979 | |
| 980 | if (!empty($form['attributes'])) { |
| 981 | $form['attributes']['#tree'] = TRUE; |
| 982 | |
| 983 | $form['submit'] = array( |
| 984 | '#type' => 'submit', |
| 985 | '#value' => t('Submit'), |
| 986 | '#weight' => 10, |
| 987 | ); |
| 988 | } |
| 989 | |
| 990 | $form['id'] = array( |
| 991 | '#type' => 'value', |
| 992 | '#value' => $id, |
| 993 | ); |
| 994 | $form['type'] = array( |
| 995 | '#type' => 'value', |
| 996 | '#value' => $type, |
| 997 | ); |
| 998 | |
| 999 | return $form; |
| 1000 | } |
| 1001 | |
| 1002 | /** |
| 1003 | * Display the option form. |
| 1004 | * |
| 1005 | * @ingroup themeable |
| 1006 | */ |
| 1007 | function theme_uc_object_options_form($form) { |
| 1008 | $header = array(t('Attribute'), t('Options'), t('Default'), t('Cost'), t('Price'), t('Weight'), t('Order')); |
| 1009 | |
| 1010 | foreach (element_children($form['attributes']) as $key) { |
| 1011 | $row = array(); |
| 1012 | $row[] = array('data' => drupal_render($form['attributes'][$key]['aid']) . drupal_render($form['attributes'][$key]['name']), 'class' => 'attribute'); |
| 1013 | |
| 1014 | if (element_children($form['attributes'][$key]['default'])) { |
| 1015 | $first = TRUE; |
| 1016 | foreach (element_children($form['attributes'][$key]['default']) as $oid) { |
| 1017 | $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['select']); |
| 1018 | $row[] = drupal_render($form['attributes'][$key]['default'][$oid]); |
| 1019 | $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['cost']); |
| 1020 | $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['price']); |
| 1021 | $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['weight']); |
| 1022 | $row[] = drupal_render($form['attributes'][$key]['options'][$oid]['ordering']); |
| 1023 | |
| 1024 | if (!$first) { |