/** * Returns an array of values for this Attribute. * * If the array has not been initialized, the method tries to * do so from the database. * The array has the form * array( * option ID => array( * 'id' => option ID, * 'attribute_id' => Attribute ID, * 'value' => value name, * 'price' => price, * ), * ... more ... * ); * For relations to the associated Product, if any, see * {@link getRelationArray}. * @access public * @return array Array of Options * upon success, false otherwise. * @global ADONewConnection */ function getOptionArray() { if (!is_array($this->arrValues)) { $this->arrValues = Attributes::getOptionArrayByAttributeId($this->id); } return $this->arrValues; }
/** * Add the option IDs of the given Attribute ID to the Order item * * Will add error messages using {@see Message::error()}, if any. * The $arrOptionIds array must have the form * array(attribute_id => array(option_id, ...)) * @param integer $item_id The Order item ID * @param integer $attribute_id The Attribute ID * @param array $arrOptionIds The array of option IDs * @return boolean True on success, false otherwise * @static */ static function insertAttribute($item_id, $attribute_id, $arrOptionIds) { global $objDatabase, $_ARRAYLANG; $objAttribute = Attribute::getById($attribute_id); if (!$objAttribute) { return \Message::error($_ARRAYLANG['TXT_SHOP_ERROR_INVALID_ATTRIBUTE_ID']); } $name = $objAttribute->getName(); $_arrOptions = Attributes::getOptionArrayByAttributeId($attribute_id); foreach ($arrOptionIds as $option_id) { $arrOption = null; if ($objAttribute->getType() >= Attribute::TYPE_TEXT_OPTIONAL) { // There is exactly one option record for these // types. Use that and overwrite the empty name with // the text or file name. $arrOption = current($_arrOptions); $arrOption['value'] = $option_id; } else { // Use the option record for the option ID given $arrOption = $_arrOptions[$option_id]; } if (!is_array($arrOption)) { \Message::error($_ARRAYLANG['TXT_SHOP_ERROR_INVALID_OPTION_ID']); continue; } $query = "\n INSERT INTO `" . DBPREFIX . "module_shop" . MODULE_INDEX . "_order_attributes`\n SET `item_id`={$item_id},\n `attribute_name`='" . addslashes($name) . "',\n `option_name`='" . addslashes($arrOption['value']) . "',\n `price`='" . $arrOption['price'] . "'"; $objResult = $objDatabase->Execute($query); if (!$objResult) { return \Message::error($_ARRAYLANG['TXT_ERROR_INSERTING_ORDER_ITEM_ATTRIBUTE']); } } return true; }
/** * Set up the HTML elements for all the Product Attributes of any Product. * * The following types of Attributes are supported: * 0 Dropdown menu, customers may select no (the default) or one option. * 1 Radio buttons, customers need to select one option. * 2 Checkboxes, customers may select no, one or several options. * 3 Dropdown menu, customers need to select one option. * 4 Optional text field * 5 Mandatory text field * 6 Optional file upload field * 7 Mandatory file upload field * Types 1 and 3 are functionally identical, they only differ by * the kind of widget being used. * The individual Product Attributes carry a unique ID enabling the * JavaScript code contained within the Shop page to verify that * all mandatory choices have been made before any Product can * be added to the cart. * @param integer $product_id The Product ID * @param string $formName The name of the HTML form containing * the Product and options * @param integer $cart_id The optional cart Product ID, * null if not applicable. * @param boolean $flagUpload If a product has an upload * Attribute associated with it, * this parameter will be set to true * @return string The string with the HTML code */ static function productOptions($product_id, $formName, $cart_id = null, &$flagUpload = false) { global $_ARRAYLANG; //\DBG::log("productOptions($product_id, $formName, $cart_id, $flagUpload): Entered"); // Semicolon separated list of Attribute name IDs to verify // before the Product is added to the cart $checkOptionIds = ''; // check if the product option block exists in the template if (self::$objTemplate->blockExists('shopProductOptionsRow') && self::$objTemplate->blockExists('shopProductOptionsValuesRow')) { $domId = 0; $count = 0; $arrAttributes = Attributes::getArray($count, null, null, '`ord` ASC', array('product_id' => $product_id)); //\DBG::log("Attributes: ".var_export($arrAttributes, true)); // When there are no Attributes for this Product, hide the // options blocks if (empty($arrAttributes)) { self::$objTemplate->hideBlock('shopProductOptionsRow'); self::$objTemplate->hideBlock('shopProductOptionsValuesRow'); } else { // Loop through the Attribute Names for the Product foreach ($arrAttributes as $attribute_id => $objAttribute) { $mandatory = false; $arrOptions = Attributes::getOptionArrayByAttributeId($attribute_id); $arrRelation = Attributes::getRelationArray($product_id); // This attribute does not apply for this product if (empty($arrRelation)) { continue; } $selectValues = ''; // create head of option menu/checkbox/radiobutton switch ($objAttribute->getType()) { case Attribute::TYPE_CHECKBOX: case Attribute::TYPE_TEXT_OPTIONAL: case Attribute::TYPE_UPLOAD_OPTIONAL: case Attribute::TYPE_TEXTAREA_OPTIONAL: case Attribute::TYPE_EMAIL_OPTIONAL: case Attribute::TYPE_EMAIL_OPTIONAL: case Attribute::TYPE_URL_OPTIONAL: case Attribute::TYPE_DATE_OPTIONAL: case Attribute::TYPE_NUMBER_INT_OPTIONAL: case Attribute::TYPE_NUMBER_FLOAT_OPTIONAL: // No container nor hidden field for optional types break; case Attribute::TYPE_MENU_OPTIONAL: // There is no hidden input field here either, // but the dropdown menu container $selectValues = '<select name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" style="width:180px;">' . "\n" . '<option value="0">' . $objAttribute->getName() . ' ' . $_ARRAYLANG['TXT_CHOOSE'] . "</option>\n"; break; case Attribute::TYPE_RADIOBUTTON: case Attribute::TYPE_TEXT_MANDATORY: case Attribute::TYPE_UPLOAD_MANDATORY: case Attribute::TYPE_TEXTAREA_MANDATORY: case Attribute::TYPE_EMAIL_MANDATORY: case Attribute::TYPE_URL_MANDATORY: case Attribute::TYPE_DATE_MANDATORY: case Attribute::TYPE_NUMBER_INT_MANDATORY: case Attribute::TYPE_NUMBER_FLOAT_MANDATORY: $mandatory = true; // The Attribute name, indicating a mandatory option. $selectValues = '<input type="hidden" id="productOption-' . $product_id . '-' . $attribute_id . '" value="' . $objAttribute->getName() . '" />' . "\n"; // The Attribute verification regex, if applicable $regex = Attribute::getVerificationRegex($objAttribute->getType()); if ($regex != '') { $selectValues .= '<input type="hidden" id="attributeVerification-' . $product_id . '-' . $attribute_id . '" value="' . $regex . '" />' . "\n"; } $checkOptionIds .= "{$attribute_id};"; break; case Attribute::TYPE_MENU_MANDATORY: $selectValues = '<input type="hidden" id="productOption-' . $product_id . '-' . $attribute_id . '" value="' . $objAttribute->getName() . '" />' . "\n" . '<select name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" style="width:180px;">' . "\n" . (count($arrOptions) > 1 ? '<option value="0">' . $objAttribute->getName() . ' ' . $_ARRAYLANG['TXT_CHOOSE'] . "</option>\n" : ''); $checkOptionIds .= "{$attribute_id};"; break; } $i = 0; foreach ($arrOptions as $option_id => $arrOption) { // This option does not apply to this product if (!isset($arrRelation[$option_id])) { continue; } $option_price = ''; $selected = false; // Show the price only if non-zero if ($arrOption['price'] != 0) { $option_price = ' (' . Currency::getCurrencyPrice($arrOption['price']) . ' ' . Currency::getActiveCurrencySymbol() . ')'; } // mark the option value as selected if it was before // and this page was requested from the cart if (isset($cart_id)) { $options = Cart::get_options_array($cart_id, $attribute_id); if (is_array($options) && in_array($option_id, $options)) { $selected = true; } } // create option menu/checkbox/radiobutton switch ($objAttribute->getType()) { case Attribute::TYPE_MENU_OPTIONAL: $selectValues .= '<option value="' . $option_id . '" ' . ($selected ? 'selected="selected"' : '') . ' >' . $arrOption['value'] . $option_price . "</option>\n"; break; case Attribute::TYPE_RADIOBUTTON: $selectValues .= '<input type="radio" name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" value="' . $option_id . '"' . ($selected ? ' checked="checked"' : '') . ' /><label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '"> ' . $arrOption['value'] . $option_price . "</label><br />\n"; break; case Attribute::TYPE_CHECKBOX: $selectValues .= '<input type="checkbox" name="productOption[' . $attribute_id . '][' . $i . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" value="' . $option_id . '"' . ($selected ? ' checked="checked"' : '') . ' /><label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '"> ' . $arrOption['value'] . $option_price . "</label><br />\n"; break; case Attribute::TYPE_MENU_MANDATORY: $selectValues .= '<option value="' . $option_id . '"' . ($selected ? ' selected="selected"' : '') . ' >' . $arrOption['value'] . $option_price . "</option>\n"; break; case Attribute::TYPE_TEXT_OPTIONAL: case Attribute::TYPE_TEXT_MANDATORY: // $option_price = ' '; $selectValues .= '<input type="text" name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" value="' . $arrOption['value'] . '" style="width:180px;" />' . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; case Attribute::TYPE_EMAIL_OPTIONAL: case Attribute::TYPE_EMAIL_MANDATORY: // $option_price = ' '; $selectValues .= '<input type="text" name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" value="' . $arrOption['value'] . '" style="width:180px;" />' . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; case Attribute::TYPE_URL_OPTIONAL: case Attribute::TYPE_URL_MANDATORY: // $option_price = ' '; $selectValues .= '<input type="text" name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" value="' . $arrOption['value'] . '" style="width:180px;" />' . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; case Attribute::TYPE_DATE_OPTIONAL: case Attribute::TYPE_DATE_MANDATORY: // $option_price = ' '; // Passed by reference $element_id = 'productOption-' . $product_id . '-' . $attribute_id . '-' . $domId; $selectValues .= \Html::getDatepicker('productOption[' . $attribute_id . ']', array('defaultDate' => $arrOption['value']), 'style="width:180px;"', $element_id) . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; case Attribute::TYPE_NUMBER_INT_OPTIONAL: case Attribute::TYPE_NUMBER_INT_MANDATORY: // $option_price = ' '; $selectValues .= '<input type="text" name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" value="' . $arrOption['value'] . '" style="width:180px;" />' . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; case Attribute::TYPE_NUMBER_FLOAT_OPTIONAL: case Attribute::TYPE_NUMBER_FLOAT_MANDATORY: // $option_price = ' '; $selectValues .= '<input type="text" name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" value="' . $arrOption['value'] . '" style="width:180px;" />' . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; case Attribute::TYPE_UPLOAD_OPTIONAL: case Attribute::TYPE_UPLOAD_MANDATORY: // $option_price = ' '; $selectValues .= '<input type="file" name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" style="width:180px;" />' . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; case Attribute::TYPE_TEXTAREA_OPTIONAL: case Attribute::TYPE_TEXTAREA_MANDATORY: // $valuePrice = ' '; $selectValues .= '<textarea name="productOption[' . $attribute_id . ']" id="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '" style="width:300px;">' . contrexx_input2xhtml($arrOption['value']) . '</textarea>' . '<label for="productOption-' . $product_id . '-' . $attribute_id . '-' . $domId . '">' . $option_price . "</label><br />\n"; break; } ++$i; ++$domId; } // create foot of option menu/checkbox/radiobutton switch ($objAttribute->getType()) { case Attribute::TYPE_MENU_OPTIONAL: $selectValues .= "</select><br />"; break; case Attribute::TYPE_RADIOBUTTON: $selectValues .= "<br />"; break; case Attribute::TYPE_CHECKBOX: $selectValues .= ""; break; case Attribute::TYPE_MENU_MANDATORY: $selectValues .= "</select><br />"; break; // Set enctype in form if one of these is present // Set enctype in form if one of these is present case Attribute::TYPE_UPLOAD_OPTIONAL: case Attribute::TYPE_UPLOAD_MANDATORY: // Avoid code analyzer warning $flagUpload = true || $flagUpload; break; /* Nothing to to case Attribute::TYPE_TEXT_OPTIONAL: case Attribute::TYPE_TEXT_MANDATORY: case Attribute::TYPE_TEXTAREA_OPTIONAL: case Attribute::TYPE_TEXTAREA_MANDATORY: case Attribute::TYPE_EMAIL_OPTIONAL: case Attribute::TYPE_EMAIL_MANDATORY: case Attribute::TYPE_URL_OPTIONAL: case Attribute::TYPE_URL_MANDATORY: case Attribute::TYPE_DATE_OPTIONAL: case Attribute::TYPE_DATE_MANDATORY: case Attribute::TYPE_NUMBER_INT_OPTIONAL: case Attribute::TYPE_NUMBER_INT_MANDATORY: case Attribute::TYPE_NUMBER_FLOAT_OPTIONAL: case Attribute::TYPE_NUMBER_FLOAT_MANDATORY: */ } $selectValues .= "\n"; self::$objTemplate->setVariable(array('SHOP_PRODCUT_OPTION' => $selectValues, 'SHOP_PRODUCT_OPTION' => $selectValues, 'SHOP_PRODUCT_OPTIONS_NAME' => $objAttribute->getName(), 'SHOP_PRODUCT_OPTIONS_TITLE' => '<a href="javascript:{}" onclick="toggleOptions(' . $product_id . ', this)" title="' . $_ARRAYLANG['TXT_OPTIONS'] . '">' . $_ARRAYLANG['TXT_OPTIONS'] . "</a>\n")); if ($mandatory && self::$objTemplate->blockExists('product_attribute_mandatory')) { self::$objTemplate->touchBlock('product_attribute_mandatory'); } self::$objTemplate->parse('shopProductOptionsValuesRow'); } self::$objTemplate->parse('shopProductOptionsRow'); } } return "return checkProductOption('shopProductForm{$formName}', " . "{$product_id}, '" . substr($checkOptionIds, 0, strlen($checkOptionIds) - 1) . "');"; }
/** * Partial view of the Attributes for a Product being edited * * Only called by {@see view_product_edit()}. * Mind that the $product_id may be empty (usually zero) for new Products. * @access private * @param integer $product_id The ID of the Product being edited * @return void */ private static function viewpart_product_attributes($product_id = null) { $i = 0; $count = 0; // If a Product is selected, check those Product Attribute values // associated with it $arrRelation = Attributes::getRelationArray($product_id); foreach (Attributes::getArray($count) as $attribute_id => $objAttribute) { // All options available for this Product Attribute $arrOptions = Attributes::getOptionArrayByAttributeId($attribute_id); $nameSelected = false; $order = 0; foreach ($arrOptions as $option_id => $arrOption) { $valueSelected = false; if (in_array($option_id, array_keys($arrRelation))) { $valueSelected = true; $nameSelected = true; $order = $arrRelation[$option_id]; } self::$objTemplate->setVariable(array('SHOP_PRODUCTS_ATTRIBUTE_ID' => $attribute_id, 'SHOP_PRODUCTS_ATTRIBUTE_VALUE_ID' => $option_id, 'SHOP_PRODUCTS_ATTRIBUTE_VALUE_TEXT' => $arrOption['value'] . ' (' . $arrOption['price'] . ' ' . Currency::getDefaultCurrencySymbol() . ')', 'SHOP_PRODUCTS_ATTRIBUTE_VALUE_SELECTED' => $valueSelected ? \Html::ATTRIBUTE_CHECKED : '')); self::$objTemplate->parse('optionList'); } self::$objTemplate->setVariable(array('SHOP_PRODUCTS_ATTRIBUTE_ROW_CLASS' => 'row' . (++$i % 2 + 1), 'SHOP_PRODUCTS_ATTRIBUTE_ID' => $attribute_id, 'SHOP_PRODUCTS_ATTRIBUTE_NAME' => $objAttribute->getName(), 'SHOP_PRODUCTS_ATTRIBUTE_SELECTED' => $nameSelected ? \Html::ATTRIBUTE_CHECKED : '', 'SHOP_PRODUCTS_ATTRIBUTE_DISPLAY_TYPE' => $nameSelected ? 'block' : 'none', 'SHOP_PRODUCTS_ATTRIBUTE_SORTID' => $order)); self::$objTemplate->parse('attributeList'); } }