_dbAdapter) { $config = Mage::getConfig(); $dbConfig = $config->getResourceConnectionConfig('default_setup'); $dbAdapter = new Zend_Db_Adapter_Pdo_Mysql(array( 'dbname' => $dbConfig->dbname, 'host' => $dbConfig->host, 'username' => $dbConfig->username, 'password' => $dbConfig->password, )); $dbAdapter->query('SET NAMES UTF8'); $this->_dbAdapter = $dbAdapter; } return $this->_dbAdapter; } protected function _getSelect() { if (null == $this->_select) { $this->_select = new Zend_Db_Select($this->_getDbAdapter()); } return $this->_select->reset(); } public function addAction() { $cart = $this->_getCart(); $params = $this->getRequest()->getParams(); if ($params['isAjax'] == 1) { $response = array(); try { if (isset($params['qty'])) { $filter = new Zend_Filter_LocalizedToNormalized( array('locale' => Mage::app()->getLocale()->getLocaleCode()) ); $params['qty'] = $filter->filter($params['qty']); } $product = $this->_initProduct(); $related = $this->getRequest()->getParam('related_product'); if ($product->getTypeId() == 'configurable') { $response = $this->_addConfigurableProduct($product); } else { /** * Check product availability */ if (!$product) { $response['status'] = 'ERROR'; $response['message'] = $this->__('Unable to find Product ID'); } $cart->addProduct($product, $params); if (!empty($related)) { $cart->addProductsByIds(explode(',', $related)); } $cart->save(); $this->_getSession()->setCartWasUpdated(true); /** * @todo remove wishlist observer processAddToCart */ Mage::dispatchEvent('checkout_cart_add_product_complete', array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()) ); if (!$cart->getQuote()->getHasError()) { $message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->htmlEscape($product->getName())); $response['status'] = 'SUCCESS'; $response['message'] = $message; $this->loadLayout(); $sidebar_header = $this->getLayout()->getBlock('cart_top')->toHtml(); Mage::register('referrer_url', $this->_getRefererUrl()); $response['cart_top'] = $sidebar_header; } } } catch (Mage_Core_Exception $e) { $msg = ""; if ($this->_getSession()->getUseNotice(true)) { $msg = $e->getMessage(); } else { $messages = array_unique(explode("\n", $e->getMessage())); foreach ($messages as $message) { $msg .= $message . '
'; } } $response['status'] = 'ERROR'; $response['message'] = $msg; } catch (Exception $e) { $response['status'] = 'ERROR'; $response['message'] = $this->__('Cannot add the item to shopping cart.'); Mage::logException($e); } $this->_sendJson($response); return; } else { return parent::addAction(); } } public function optionsAction() { $productId = $this->getRequest()->getParam('product_id'); // Prepare helper and params $viewHelper = Mage::helper('catalog/product_view'); $params = new Varien_Object(); $params->setCategoryId(false); $params->setSpecifyOptions(false); // Render page try { $viewHelper->prepareAndRender($productId, $this, $params); } catch (Exception $e) { if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) { if (isset($_GET['store']) && !$this->getResponse()->isRedirect()) { $this->_redirect(''); } elseif (!$this->getResponse()->isRedirect()) { $this->_forward('noRoute'); } } else { Mage::logException($e); $this->_forward('noRoute'); } } } /** * send json respond * * @param array $response - response data */ private function _sendJson( $response ) { $this->getResponse()->setHeader('Content-type', 'application/json'); $this->getResponse()->setBody( (string) $this->getRequest()->getParam('callback') . '(' . Mage::helper('core')->jsonEncode($response) . ')' ); } /** * Update product configuration for a cart item */ public function updateItemOptionsAction() { $cart = $this->_getCart(); $id = (int) $this->getRequest()->getParam('id'); $params = $this->getRequest()->getParams(); if (!isset($params['options'])) { $params['options'] = array(); } if ($params['isAjax'] == 1) { $response = array('params' => $params); try { if (isset($params['qty'])) { $filter = new Zend_Filter_LocalizedToNormalized( array('locale' => Mage::app()->getLocale()->getLocaleCode()) ); $params['qty'] = $filter->filter($params['qty']); } $quoteItem = $cart->getQuote()->getItemById($id); if (!$quoteItem) { $this->_sendJson(array( 'status' => 'ERROR', 'message' => $this->__('Quote item is not found.'), )); return; } $item = $cart->updateItem($id, new Varien_Object($params)); if (is_string($item)) { $this->_sendJson(array( 'status' => 'ERROR', 'message' => $item, )); return; } if ($item->getHasError()) { Mage::throwException($item->getMessage()); $this->_sendJson(array( 'status' => 'ERROR', 'message' => $item->getMessage(), )); return; } $related = $this->getRequest()->getParam('related_product'); if (!empty($related)) { $cart->addProductsByIds(explode(',', $related)); } $cart->save(); $this->_getSession()->setCartWasUpdated(true); Mage::dispatchEvent('checkout_cart_update_item_complete', array('item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse()) ); if (!$this->_getSession()->getNoCartRedirect(true)) { if (!$cart->getQuote()->getHasError()){ $response['status'] = 'SUCCESS'; $response['message'] = $this->__('%s was updated in your shopping cart.', Mage::helper('core')->htmlEscape($item->getProduct()->getName())); $this->loadLayout(); Mage::register('referrer_url', $this->_getRefererUrl()); $sidebar_header = $this->getLayout()->getBlock('cart_top')->toHtml(); $response['cart_top'] = $sidebar_header; } } } catch (Mage_Core_Exception $e) { $msg = ""; if ($this->_getSession()->getUseNotice(true)) { $msg = $e->getMessage(); } else { $messages = array_unique(explode("\n", $e->getMessage())); foreach ($messages as $message) { $msg .= $message . '
'; } } $response['status'] = 'ERROR'; $response['message'] = $msg; } catch (Exception $e) { $response['status'] = 'ERROR'; $response['message'] = $this->__('Cannot update the item.'); Mage::logException($e); } $this->_sendJson($response); return; } else { return parent::updateItemOptionsAction(); } } protected function _getOwnedProducts($params, $product) { $optionIds = array(); $optionSelectedItemsIds = array(); if (!empty($params['options'])) { $options = $params['options']; foreach ($options as $optionId => $optionInfo) { if (is_array($optionInfo)) { $optionIds[] = $optionId; $optionSelectedItemsIds = array_merge($optionSelectedItemsIds, $optionInfo); } } } $collection = Mage::getSingleton('catalog/product_option_value')->getCollection(); $collection->addFieldToSelect('*') ->addFieldToFilter('option_id', array('in' => $optionIds)); $productsSkuList = array(); foreach ($collection as $optionValue) { if (in_array($optionValue->getId(), $optionSelectedItemsIds)) { $productsSkuList[] = $optionValue->getSku(); } } $beads = null; $threads = null; $specialProduct = null; $productCollection = Mage::getSingleton('catalog/product') ->setStoreId(Mage::app()->getStore()->getId()) ->getCollection(); $productCollection->addFieldToFilter('sku', array('in' => $productsSkuList)); foreach ($productCollection as $selectedProduct) { /** @var Mage_Catalog_Model_Product $selectedProduct */ $attributeSetId = $selectedProduct->getAttributeSetId(); if (self::BEADS_ATTRIBUTE_SET_ID == $attributeSetId) { $beads = Mage::getModel('catalog/product')->load($selectedProduct->getId(), '*'); } else if (self::THREADS_ATTRIBUTE_SET_ID == $attributeSetId) { $threads = Mage::getModel('catalog/product')->load($selectedProduct->getId(), '*'); } else { $specialProduct = Mage::getModel('catalog/product')->load($selectedProduct->getId(), '*'); } /** @var Mage_CatalogInventory_Model_Stock_Item $stockItem */ $stockItem = Mage::getModel('cataloginventory/stock_item'); $stockItem->setProduct($selectedProduct); $selectedProduct->setStockItem($stockItem); } /** @var Mage_Catalog_Model_Resource_Product_Collection $productCollection */ $productCollection = Mage::getModel('catalog/product') ->setStoreId(Mage::app()->getStore()->getId()) ->getCollection() ->addFieldToFilter('attribute_set_id', array('in' => $this->_configurableProductComponents)) ->addFieldToFilter('type_id', array('eq' => 'simple')); $attributes = $product->getAttributeSetId() == self::PRODUCT_PICTURE_BASE ? $this->_configurableProductAttributes4Picture : $this->_configurableProductAttributes; foreach ($attributes as $name) { if ('base_size' !== $name || !count(array_intersect($this->_categoriesWithoutSize, $product->getCategoryIds()))) { if ('picture_size' !== $name) { $productCollection->addFieldToFilter($name, array('eq' => $product->getData($name))); } else { $productCollection->addFieldToFilter('base_size', array( 'eq' => $this->_getBaseSizeAttributeValueId($product->getData($name)) )); } } } $productCollection->getSelect() ->join(array('a' => 'eav_attribute'), 'a.attribute_code = "group_key"', null) ->join( array('v' => 'catalog_product_entity_varchar'), 'a.attribute_id = v.attribute_id AND v.entity_id = e.entity_id AND v.value = "' . $product->getData('group_key') . '"', null ); foreach ($productCollection as $selectedProduct) { /** @var Mage_Catalog_Model_Product $selectedProduct */ $attributeSetId = $selectedProduct->getAttributeSetId(); if (self::BEADS_ATTRIBUTE_SET_ID == $attributeSetId && null !== $beads) { $beads = Mage::getModel('catalog/product')->load($selectedProduct->getId(), '*'); } else if (self::THREADS_ATTRIBUTE_SET_ID == $attributeSetId && null !== $threads) { $threads = Mage::getModel('catalog/product')->load($selectedProduct->getId(), '*'); } else { continue; } /** @var Mage_CatalogInventory_Model_Stock_Item $stockItem */ $stockItem = Mage::getModel('cataloginventory/stock_item'); $stockItem->setProduct($selectedProduct); $selectedProduct->setStockItem($stockItem); } return array($beads, $threads, $specialProduct); } protected function _getBaseSizeAttributeValueId($pictureSizeValue) { /** @var Zend_Db_Select $select */ $select = Mage::getModel('catalog/product')->getCollection()->getSelect(); $select->reset(); $select->from(array('a' => 'eav_attribute'), null) ->join(array('o' => 'eav_attribute_option'), 'o.attribute_id = a.attribute_id', null) ->join( array('v2' => 'eav_attribute_option_value'), 'v2.store_id = 0 AND v2.option_id = ' . (int) $pictureSizeValue, null) ->join( array('v' => 'eav_attribute_option_value'), 'o.option_id = v.option_id AND v.store_id = 0 AND v.value = v2.value', array('option_id') ) ->where('a.attribute_code = "base_size"'); return $select->getAdapter()->fetchOne($select); } protected function _getConfigurableProductCustomOptions($oldProduct) { $params = $this->getRequest()->getParams(); $configurableProductCustomOptions = array(); foreach ($oldProduct->getOptions() as $option) { /** @var Mage_Catalog_Model_Product_Option $option */ $type = $option->getType(); if ($type == 'drop_down') { $value = $params['options'][$option->getId()]; } else if ($type == 'field') { $value = $params['options'][$option->getId()]; } else { continue; } if ($value) { $configurableProductCustomOptions[$option->getSortOrder()] = array( 'value' => $value, 'drop_down' => $type == 'drop_down' ? $option->getId() : false, ); } } return $configurableProductCustomOptions; } protected function _prepareCustomOptions($product, $configurableProductCustomOptions) { $preparedCustomOptionArray = array(); $collection = Mage::getModel('catalog/product_option')->getCollection() ->addFieldToSelect('*') ->addFieldToFilter('product_id', array('eq' => $product->getId())) ->addFieldToFilter( 'sort_order', array('in' => array_keys($configurableProductCustomOptions)) ); foreach ($collection as $option) { $sortOrder = $option->getSortOrder(); $code = 'option_' . $option->getId(); $value = $configurableProductCustomOptions[$sortOrder]['value']; if ($optionId = $configurableProductCustomOptions[$sortOrder]['drop_down']) { $select = $this->_getSelect(); $joinWhere = 'option_id = ' . $optionId . ' AND j.option_type_id = m.option_type_id' . ' AND store_id = 0' . ' AND j.option_type_id = ' . $value; $select->from( array('m' => 'catalog_product_option_type_title'), array('title') ) ->join(array('j' => 'catalog_product_option_type_value'), $joinWhere); $result = $select->query()->fetch(); $title = $result['title']; $joinWhere = 'option_id = ' . $option->getId() . ' AND j.option_type_id = m.option_type_id' . ' AND store_id = 0' . ' AND title = \'' . $title . '\''; $select->reset(); $select->from( array('m' => 'catalog_product_option_type_value'), array('option_type_id') ) ->join(array('j' => 'catalog_product_option_type_title'), $joinWhere); $result = $select->query()->fetch(); $value = $result['option_type_id']; } $preparedCustomOptionArray[$option->getId()] = array( 'code' => $code, 'value' => $value, ); } return $preparedCustomOptionArray; } protected function _checkExistsItemsWithCurrentProduct($product, $preparedCustomOptionArray) { $cart = $this->_getCart(); $itemIds = array(); /** @var Mage_Sales_Model_Quote_Item $item */ foreach ($cart->getItems() as $item) { if ($item->getProductId() == $product->getId()) { $itemIds[] = $item->getId(); } } $existsItemId = false; if (!empty($itemIds)) { $select = $this->_getSelect(); $where = 'item_id IN (\'' . implode('\',\'', $itemIds) . '\')' . ' AND code = \'option_ids\''; $select->from('sales_flat_quote_item_option', array('item_id', 'value')) ->where($where); $result = $select->query()->fetchAll(); $optionsCount = count($preparedCustomOptionArray); if ($optionsCount) { $similarItemIdsList = array(); foreach ($result as $row) { $existsItemCustomOptionIds = explode(',', $row['value']); if (count($existsItemCustomOptionIds) == $optionsCount) { foreach ($preparedCustomOptionArray as $optionId => $optionInfo) { if (!in_array($optionId, $existsItemCustomOptionIds)) { continue 2; } if (!in_array($row['item_id'], $similarItemIdsList)) { $similarItemIdsList[] = $row['item_id']; } } } } if (!empty($similarItemIdsList)) { $select->reset(); $optionsCodes = array(); foreach (array_keys($preparedCustomOptionArray) as $optionId) { $optionsCodes[] = 'option_' . $optionId; } $where = 'code IN (\'' . implode('\',\'', $optionsCodes) . '\')' . ' AND item_id IN (\'' . implode('\',\'', $similarItemIdsList) . '\')'; $select->from('sales_flat_quote_item_option', array('item_id', 'value', 'code')) ->where($where); $result = $select->query()->fetchAll(); $preparedResult = array(); foreach ($result as $row) { $itemId = $row['item_id']; $code = intval(substr($row['code'], 7)); if (!isset($preparedResult[$itemId])) { $preparedResult[$itemId] = array(); } $preparedResult[$itemId][$code] = $row['value']; } $preparedExistsResult = array(); foreach ($preparedCustomOptionArray as $optionId => $optionInfo) { $preparedExistsResult[$optionId] = $optionInfo['value']; } foreach ($preparedResult as $itemId => $values) { if ($values == $preparedExistsResult) { $existsItemId = $itemId; break; } } } } else { $notEmptyItems = array(); foreach ($result as $row) { $notEmptyItems[] = $row['item_id']; } foreach ($itemIds as $itemId) { if (!in_array($itemId, $notEmptyItems)) { $existsItemId = $itemId; break; } } } } return $existsItemId; } protected function _getItem($existsItemId, $product, $preparedCustomOptionArray, $qty) { $cart = $this->_getCart(); if (false === $existsItemId) { $item = Mage::getModel('sales/quote_item')->setProduct($product); if (!empty($preparedCustomOptionArray)) { $item->addOption(new Varien_Object(array( 'product' => $product, 'code' => 'option_ids', 'value' => implode(',', array_keys($preparedCustomOptionArray)), ))); foreach ($preparedCustomOptionArray as $optionInfo) { $item->addOption(new Varien_Object(array( 'product' => $product, 'code' => $optionInfo['code'], 'value' => $optionInfo['value'], ))); } } $item->setQty($qty); } else { $item = $cart->getItems()->getItemById($existsItemId); $item->setQty($item->getQty() + $qty); } return $item; } protected function _addSpecialProduct($oldProduct, $qty, $product) { $cart = $this->_getCart(); $configurableProductCustomOptions = $this->_getConfigurableProductCustomOptions($oldProduct); $preparedCustomOptionArray = $this->_prepareCustomOptions($product, $configurableProductCustomOptions); $existsItemId = $this->_checkExistsItemsWithCurrentProduct($product, $preparedCustomOptionArray); /** @var Mage_Sales_Model_Quote_Item $item */ $item = $this->_getItem($existsItemId, $product, $preparedCustomOptionArray, $qty); $cart->getQuote()->addItem($item); } protected function _addConfigurableProduct($product) { $response = array(); $cart = $this->_getCart(); $params = $this->getRequest()->getParams(); $qty = $params['qty'] > 0 ? $params['qty'] : 1; $oldProduct = $product; /** @var Mage_Catalog_Model_Product_Type_Configurable $configurableProduct */ $configurableProduct = Mage::getModel('catalog/product_type_configurable'); /** @var Mage_Catalog_Model_Product $product */ $product = $configurableProduct->getProductByAttributes( $params['super_attribute'], $product ); $product = Mage::getModel('catalog/product')->load($product->getId(), '*'); list($beads, $threads, $specialProduct) = $this->_getOwnedProducts($params, $product); if ($specialProduct) { $product = $specialProduct; $this->_addSpecialProduct($oldProduct, $qty, $product); } else { if (!$product) { $response['status'] = 'ERROR'; $response['message'] = $this->__('Unable to find Product ID'); } $cart->addProduct($product, $params); } if ($beads) { $cart->addProduct($beads, array('qty' => $params['qty'])); } if ($threads) { $cart->addProduct($threads, array('qty' => $params['qty'])); } $cart->save(); $this->_getSession()->setCartWasUpdated(true); Mage::dispatchEvent('checkout_cart_add_product_complete', array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()) ); if (!$cart->getQuote()->getHasError()) { $message = $this->__('%s was added to your shopping cart.', Mage::helper('core')->htmlEscape($product->getName())); $response['status'] = 'SUCCESS'; $response['message'] = $message; $this->loadLayout(); $sidebar_header = $this->getLayout()->getBlock('cart_top')->toHtml(); Mage::register('referrer_url', $this->_getRefererUrl()); $response['cart_top'] = $sidebar_header; } return $response; } }