/** * Returns a new Attribute queried by one of its option IDs from * the database. * @param integer $option_id The option ID * @static */ static function getByOptionId($option_id) { // Get the associated Attribute ID $attribute_id = Attribute::getIdByOptionId($option_id); return Attribute::getById($attribute_id); }
/** * Returns an array of two HTML representations of the Attributes and * their respective options specified by the array given * * One of these representation may be used anywhere the matching Product * is viewed. The first (at index 0) is the long form best used in the * cart view, the second (at index 1) is suitable for the JSCart in the * sidebar. * Attributes with an empty list of option IDs will not be included in * the string produced. Invalid IDs are silently skipped. * Note that the format of the string can be easily customized by editing * the following language entries: * TXT_SHOP_OPTION_LONG_FORMAT * TXT_SHOP_OPTION_LONG_FORMAT_JOINER * TXT_SHOP_ATTRIBUTE_LONG_FORMAT * TXT_SHOP_ATTRIBUTE_LONG_FORMAT_JOINER * TXT_SHOP_OPTION_CART_FORMAT * TXT_SHOP_OPTION_CART_FORMAT_JOINER * TXT_SHOP_ATTRIBUTE_CART_FORMAT * TXT_SHOP_ATTRIBUTE_CART_FORMAT_JOINER * The array parameter must have the form * array( * Attribute ID => array( * option ID, * [...] * ), * [...], * ) * @global array $_ARRAYLANG * @param array $arrAttributesOptions The array of Attribute and * option IDs * @param float $options_price The sum of all option prices, * by reference * @return array The array of two HTML * representations of * the Attributes and options * present in the parameter array */ static function getAsStrings($arrAttributesOptions, &$options_price = NULL) { global $_ARRAYLANG; //DBG::log("Attributes::getAsStrings(".var_export($arrAttributesOptions, true).", $options_price)"); $options_price = 0; if (!is_array($arrAttributesOptions) || empty($arrAttributesOptions)) { return array('', ''); } $attributes_long = $attributes_cart = array(); foreach ($arrAttributesOptions as $attribute_id => $arrOptionIds) { //DBG::log("Attributes::getAsStrings(): Attribute ID $attribute_id"); if (empty($arrOptionIds)) { continue; } $objAttribute = Attribute::getById($attribute_id); if (!$objAttribute) { continue; } //DBG::log("Attributes::getAsStrings(): Attribute ".var_export($objAttribute, true)); $options_long = $options_cart = array(); $arrOptions = $objAttribute->getOptionArray(); foreach ($arrOptionIds as $option_id) { //DBG::log("Attributes::getAsStrings(): Option ID $option_id"); $option_name = ''; // Valid indices are: 'value', 'price', 'order' $option_price = $arrOptions[$option_id]['price']; // Note that this *MUST NOT* test for is_integer() // (which $option_id isn't -- it's either an arbitrary // string, or one that represents a positive integer), // but for a *string matching a valid ID*. // intval() doesn't do the job properly, as it also // converts "1 but true" to 1. // A good match would be done by is_numeric(); however, // this would also accept floats and scientific // notation... if (preg_match('/^[1-9][0-9]*$/', $option_id) && in_array($objAttribute->getType(), array(Attribute::TYPE_MENU_OPTIONAL, Attribute::TYPE_MENU_MANDATORY, Attribute::TYPE_RADIOBUTTON, Attribute::TYPE_CHECKBOX))) { $option_name = $arrOptions[$option_id]['value']; } else { $option_name = ShopLibrary::stripUniqidFromFilename($option_id); $path = Order::UPLOAD_FOLDER . $option_id; if ($option_name != $option_id && file_exists($path)) { $option_name = \Html::getLink('/' . $path, $option_name, 'uploadimage'); } } $options_long[] = sprintf($_ARRAYLANG['TXT_SHOP_OPTION_LONG_FORMAT'], $option_name, $option_price, Currency::getActiveCurrencyCode(), Currency::getActiveCurrencySymbol()); $options_cart[] = sprintf($_ARRAYLANG['TXT_SHOP_OPTION_CART_FORMAT'], $option_name, $option_price, Currency::getActiveCurrencyCode(), Currency::getActiveCurrencySymbol()); $options_price += $option_price; //DBG::log("Attributes::getAsStrings(): Price + $option_price = $options_price"); } if ($options_long) { $options_long = join($_ARRAYLANG['TXT_SHOP_OPTION_LONG_FORMAT_JOINER'], $options_long); $attributes_long[] = sprintf($_ARRAYLANG['TXT_SHOP_ATTRIBUTE_LONG_FORMAT'], $objAttribute->getName(), $options_long); $options_cart = join($_ARRAYLANG['TXT_SHOP_OPTION_CART_FORMAT_JOINER'], $options_cart); $attributes_cart[] = sprintf($_ARRAYLANG['TXT_SHOP_ATTRIBUTE_CART_FORMAT'], $objAttribute->getName(), $options_cart); } } if ($attributes_long) { $attributes_long = join($_ARRAYLANG['TXT_SHOP_ATTRIBUTE_LONG_FORMAT_JOINER'], $attributes_long); $attributes_cart = join($_ARRAYLANG['TXT_SHOP_ATTRIBUTE_CART_FORMAT_JOINER'], $attributes_cart); } return array($attributes_long, $attributes_cart); }
/** * 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; }
/** * Adds a single Product to the Cart * @param array $arrNewProduct The array of Product data * @param integer $old_cart_id The optional Cart ID (index) * @static */ static function add_product($arrNewProduct, $old_cart_id = null) { //DBG::log("Cart::add_product(): Entered, Items: ".var_export($_SESSION['shop']['cart']['items'], true)); if (empty($arrNewProduct['id'])) { //DBG::log("Cart::add_product(): No ID"); return; } // Do not add zero or negative quantities if (empty($arrNewProduct['quantity']) || intval($arrNewProduct['quantity']) <= 0) { //DBG::log("Cart::add_product(): Invalid quantity"); return; } $quantity = intval($arrNewProduct['quantity']); $products = $_SESSION['shop']['cart']['items']->toArray(); // $_SESSION is a object so convert into array $cart_id = null; // Add as a new product if true $new = true; if (is_null($old_cart_id)) { foreach ($products as $cart_id => $arrProduct) { // Check whether the same product is already in the cart if ($arrProduct['id'] != $arrNewProduct['id']) { //DBG::log("Cart::add_product(): Different ID, skipping"); continue; } //DBG::log("Cart::add_product(): Comparing options: New: ".var_export($arrNewProduct['options'], true).", Old: ".var_export($arrProduct['options'], true)); // Same ID from here, compare the options if (empty($arrNewProduct['options'])) { if (empty($arrProduct['options'])) { // Both got no options, so must be identical $new = false; //DBG::log("Cart::add_product(): Both no options, match"); break; } } else { if (empty($arrProduct['options'])) { // The new one's got options, while the old one does not //DBG::log("Cart::add_product(): Only new options, skipping"); continue; } } // Refuse invalid options if (!is_array($arrNewProduct['options'])) { //DBG::log("Cart::add_product(): Invalid options: {$arrNewProduct['options']}, exiting"); return; } $old_attribute_ids = array_keys($arrProduct['options']); sort($old_attribute_ids); $new_attribute_ids = array(); foreach ($arrNewProduct['options'] as $attribute_id => $value) { if (empty($value)) { //DBG::log("Cart::add_product(): New: no options for Attribute ID $attribute_id"); continue; } $new_attribute_ids[] = $attribute_id; } sort($new_attribute_ids); if (!$old_attribute_ids === $new_attribute_ids) { //DBG::log("Cart::add_product(): Different Attributes: New: ".var_export($new_attribute_ids, true).", Old: ".var_export($old_attribute_ids, true)); continue; } // Compare options // check for the same option values foreach ($arrNewProduct['options'] as $attribute_id => $value) { if (empty($value)) { //DBG::log("Cart::add_product(): New: Empty option value for Attribute ID $attribute_id"); continue; } if (isset($arrProduct['options'][$attribute_id]) && is_array($arrProduct['options'][$attribute_id])) { $arrPostValues = array(); if (is_array($value)) { $arrPostValues = array_values($value); } else { array_push($arrPostValues, $value); } if ($arrPostValues !== $arrProduct['options'][$attribute_id]) { //DBG::log("Cart::add_product(): Different options: New: ".var_export($arrPostValues, true).", Old: ".var_export($arrProduct['options'][$attribute_id], true)); continue 2; } } else { if (!isset($arrProduct['options'][$attribute_id][$value])) { //DBG::log("Cart::add_product(): Missing option"); continue 2; } } } // All options identical $new = false; //DBG::log("Cart::add_product(): Identical options as Cart ID $cart_id: New: ".var_export($arrNewProduct['options'], true).", Old: ".var_export($arrProduct['options'], true)); break; } //DBG::log("Cart::add_product(): No match!"); } //DBG::log("Cart::add_product(): Comparing done, cart ID $cart_id"); if ($new) { if (isset($old_cart_id)) { //DBG::log("Cart::add_product(): New Product: Replacing cart ID with old $old_cart_id"); $cart_id = $old_cart_id; } else { //DBG::log("Cart::add_product(): New Product: Creating new cart ID"); // TODO: True? // $arrNewProduct['id'] may be undefined! $arrProduct = array('id' => $arrNewProduct['id'], 'quantity' => $quantity); array_push($products, $arrProduct); $arrKeys = array_keys($products); $cart_id = $arrKeys[count($arrKeys) - 1]; } } else { if (isset($old_cart_id)) { //DBG::log("Cart::add_product(): Old Product: Have cart ID..."); if ($old_cart_id != $cart_id) { //DBG::log("Cart::add_product(): Old Product: Merging"); $products[$cart_id]['quantity'] += $products[$old_cart_id]['quantity']; unset($products[$old_cart_id]); } else { //DBG::log("Cart::add_product(): Old Product: Same cart ID, not merged!"); } } else { //DBG::log("Cart::add_product(): Old Product: Adding quantity $quantity to {$products[$cart_id]['quantity']} in cart ID $cart_id (old ID $old_cart_id)"); $products[$cart_id]['quantity'] += $quantity; //DBG::log("Cart::add_product(): Old Product: Updated quantity to {$_SESSION['shop']['cart']['items'][$cart_id]['quantity']}"); } } // Add options // TODO: I suspect that this could be completely skipped when $new === false!? $products[$cart_id]['options'] = array(); if (isset($arrNewProduct['options']) && count($arrNewProduct['options']) > 0) { //DBG::log("Cart::add_product(): Adding options: New: ".var_export($arrNewProduct['options'], true)); foreach ($arrNewProduct['options'] as $attribute_id => $option_id) { $attribute_id = intval($attribute_id); // Get Attribute $objAttribute = Attribute::getById($attribute_id); if (!$objAttribute) { continue; } $type = $objAttribute->getType(); if ($type == Attribute::TYPE_TEXT_OPTIONAL || $type == Attribute::TYPE_TEXT_MANDATORY) { if ($option_id == '') { continue; } } if ($type == Attribute::TYPE_UPLOAD_OPTIONAL || $type == Attribute::TYPE_UPLOAD_MANDATORY) { $filename = $arrNewProduct['options'][$attribute_id]; $option_id = Shop::uploadFile($filename); if ($option_id == '') { continue; } } if (!isset($products[$cart_id]['options'][$attribute_id])) { $products[$cart_id]['options'][$attribute_id] = array(); } if (is_array($option_id) && count($option_id)) { foreach ($option_id as $id) { array_push($products[$cart_id]['options'][$attribute_id], $id); } } elseif (!empty($option_id)) { array_push($products[$cart_id]['options'][$attribute_id], contrexx_input2raw($option_id)); } } } $_SESSION['shop']['cart']['items'] = $products; //DBG::log("Cart::add_product(): New options: ".var_export($products[$cart_id]['options'], true)); //DBG::log("Cart::add_product(): Leaving"); }
/** * Delete one or more Attribute * @access private * @param mixed $attribute_id The Attribute ID or an array of IDs * @return string The empty string on success, * some status message on failure */ function _deleteAttribute($attribute_id) { global $_ARRAYLANG; $arrAttributeId = $attribute_id; if (!is_array($attribute_id)) { $arrAttributeId = array($attribute_id); } foreach ($arrAttributeId as $attribute_id) { $objAttribute = Attribute::getById($attribute_id); if (!$objAttribute) { return \Message::error($_ARRAYLANG['TXT_SHOP_ATTRIBUTE_ERROR_NOT_FOUND']); } if (!$objAttribute->delete()) { return \Message::error($_ARRAYLANG['TXT_SHOP_ATTRIBUTE_ERROR_DELETING']); } } return \Message::ok($_ARRAYLANG['TXT_SHOP_ATTRIBUTE' . (count($arrAttributeId) > 1 ? 'S' : '') . '_SUCCESSFULLY_DELETED']); }