_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;
}
}