I'm currently working on a shopping application but i stumbled upon a problem. The problem is that i can't select the JSON values from my "shopping cart". See the following code and description.
So by using add to cart buttons and such i'm creating the shopping cart. The shopping cart is actually a JSON object. An example of the cart:
{"cartItems":{"2":{"id":"2","name":"Blouse","price":26.99,"size":"M","quantity":"3","total_product_price":80.97},"5":{"id":"5","name":"Bedrukte Zomerjurk","price":30.5,"size":"L","quantity":"4","total_product_price":122}},"totalPrice":202.97,"totalItems":2,"customerSelect":{"id":"1","firstname":"John","lastname":"TestStefans"}}
As you can see the design of my JSON cart is:
cart:{"cartItems":{"id":{ product information }}}
The problem now is trying to select the values like the "name" and "price". This due to the "id"{ segment. But i need that piece for removing one item by id from the cart.
So my question is:
How would i be able to select all the product information and create an foreach for placing the information in the database / email template. I've been trying this but this only gave me the first product:
$cart_encode = json_encode($_SESSION['cart']['cartItems']);
$cartDecode = json_decode($cart_encode);
// Adding the product items
foreach ($cartDecode as $key => $cartItem) {
$resource->associations->cart_rows->cart_row->id_product = $cartItem->{"id"};
$resource->associations->cart_rows->cart_row->id_product_attribute = 1;
$resource->associations->cart_rows->cart_row->id_address_delivery = 1;
$resource->associations->cart_rows->cart_row->quantity = $cartItem->{"quantity"};
}
Take note that i'm using XML for database input. For the email template i've tried:
$testName = $_SESSION['cart']['cartItems']['name'];
$testPrice = $_SESSION['cart']['cartItems']['price'];
$testQuantity = $_SESSION['cart']['cartItems']['quantity'];
$testTotal = $_SESSION['cart']['cartItems']['total_product_price'];
$testProduct = array(
"Name:" => $testName,
"Price:" => $testPrice,
"Quantity" => $testQuantity,
"Total" => $testTotal
);
Iknow that the id number is missing but i cant dynamicly avoid that layer.
I hope that my question is clear
As always. Thanks in advance!
Related
I've stumbled upon some problems while creating a shopping application. In short:
I'm using a php $_SESSION['cart'] to register all the products inside the cart
The products are registered and added to the cart by the following code:
else {// It's new: Add it to the array
$_SESSION['cart']['cartItems'][] = $cartProduct;
$_SESSION['cart']['totalItems']++;
}
To that function a cart with 2 or more products looks like this:
{"cartItems":[{
"id":"3",
"name":"Bedrukte Jurk",
"price":25.99,
"size":"L",
"quantity":"12",
"total_product_price":311.88
},
{
"id":"11",
"name":"Product voorraad id",
"price":144,
"size":"M",
"quantity":"23",
"total_product_price":3312
}
],
"totalPrice":3623.88,
"totalItems":2
}
So now i've got two questions regarding my $_SESSION['cart'];
How would i be able to delete a specific product. I was thinking about using the product id. And for now that has been working for me unless the unset($_SESSION['cart']['cartItems'] ... id part that i still haven't figured out. So how would i be able to tell php to delete the row with the requested id.
The second question is a bit more confusing to me since this has to do with writing the "cart" to the database on "payOrder" click.
So i've been struggling with this part and i've tried using a foreach() statement to get each row. But sadly only the first product is written in the database. The function handeling this foreach() is shown down below:
$cart_encode = json_encode($_SESSION['cart']['cartItems']);
$cartDecode = json_decode($cart_encode);
$date = date("Y-m-d h:i:s");
// Create the cart Using XML
$opt = $webService->get(array(
'resource' => 'carts',
));
// Define the $resource
$resource = $opt->children()->children();
// Adding the product items
foreach ($cartDecode as $key => $cartItem) {
$resource->associations->cart_rows->cart_row->id_product = $cartItem->{"id"};
$resource->associations->cart_rows->cart_row->id_product_attribute = 1;
$resource->associations->cart_rows->cart_row->id_address_delivery = 1;
$resource->associations->cart_rows->cart_row->quantity = $cartItem->{"quantity"};
}
Update after the comments
So as #Randall has mentioned it's better to use the product_id's as a new array index layer for deleting the row's in the cart, in this case a particulair product.
So i've edited my code to an older state in wich this is true and Question one is solved.
Anyhow the new JSON structure is:
{"cartItems": {
"5": {
"id":"5",
"name":"Bedrukte Zomerjurk",
"price":30.5,
"size":"L",
"quantity":"34",
"total_product_price":1037
},
"4": {
"id":"4",
"name":"Bedrukte Avond Jurk",
"price":50.99,
"size":"L",
"quantity":"3",
"total_product_price":152.97
}
},
"totalPrice":1189.97,
"totalItems":2
}
Still Question 2 sadly stays unanswered about the database input. I hope there are some people that could help me out.
PS: #Randall thanks for the "it makes no difference tip, it solved question 1 of the 2!".
I hope my question is clear and if it isn't please let me know.
As always,
Thanks in advance!
I'm currently trying to add a custom option to a specific orderline on add to cart via the following:
public function addToPackageQuote()
{
$cart = Mage::getSingleton("checkout/cart");
$quote = Mage::getSingleton("checkout/session")->getQuote();
$packageId = Mage::getModel('MyTuxedo_OPP/Package')->checkPackageId();
$products = $this->sortArray();
foreach ($products as $productInfo) {
try {
$split = explode(",", $productInfo);
$_product = Mage::getModel('catalog/product')->load($split[0]);
if($_product->isConfigurable()) {
$simpleId = $this->getConfigurableSimple($split[1],$split[3],$split[0]);
} else {
$simpleId = $split[0];
}
$product = Mage::getModel('catalog/product')->load($simpleId);
$options = new Varien_Object(array(
"qty" => 1,
"custom_options" => array(
"package" => $packageId,
"packageName" => Mage::helper('MyTuxedo_OPP')->getPackageName()
)
));
$quote->addProduct($product, $options);
$this->_getSession()->setCartWasUpdated(true);
$quote->save();
} catch (Exception $e) {
echo $e->getMessage();
}
$this->addFreeItems();
}
$cart->save();
unset($_SESSION['products']);
unset($_SESSION['productId']);
$cart->save();
// Let's unset all the package sessions (apart from a few that are needed!).
$this->kill();
}
This method is completely seperate from the generic add to cart handler, and is used purely in a packages system so that it adds simple products exclusively (also breaks down configurables super attribute to find the simple product too).
These simple products have no custom options attached to them in the Magento backend, nor is it a goal to add custom options to the product itself. What I would like to do is attach custom options to the order-line that is then transferred over to the order if a purchase is made. So effectively data that is added at the add to cart method and no where else!
The add to cart method works as expected it's just not including the custom options I am trying to attach. I have also tried defining the options object as simply:
$options = new Varien_Object(array(
"qty" => 1,
"package" => $packageId,
"packageName" => Mage::helper('MyTuxedo_OPP')->getPackageName()
)
The above info, not including qty is not in the orderline object at all, and I can't seem to work out where to move on from here.
Endlessly googling at the moment so some help would be most appreciated!!
I do appreciate I’m instantiating the product model object twice in this, however the plan is to just get it working then optimise! :)
You have to set the custom options for the product before adding it to cart.
$product->setCustomOptions($options);
The in Mage_Sales_Model_Quote::_addCatalogProduct() the custom options will be added to the cart item.
See also here: http://www.magentocommerce.com/boards/viewthread/49659/
By the way: Your code may be pretty slow because you are loading products twice in a foreach loop. You should consider some refactoring by using the product collection instead. Also it looks kind of hackish to directly access the $_SESSION variable here. You could rather use the Checkout Session for that (Mage::getSingleton('checkout/session')).
I have now resolved this, after much headache. You can add a custom option to the cart and not have to instantiate the product object and save a custom option to do this, it can be done via tacking onto an observer, and pulling the quote items.
After tacking onto: sales_quote_add_item
I then used:
public function addCustomData($observer) {
$event = $observer->getEvent();
$quote_item = $event->getQuoteItem();
$quote = $session->getQuote();
$quote_item->addOption(array("product_id" => $quote_item->getProduct()->getId(),
"product" => $quote_item->getProduct(),
"code" => 'PackageId',
"value" => Mage::getModel('MyTuxedo_OPP/Package')->checkPackageId()
));
$quote->save();
}
It is most important to include the product object and id, as the function doesn't use the loaded object for some reason.
You can then get at the object via:
$_item->getOptionByCode('PackageId')->getValue();
Quick piece of handy info, if it dumps a stack trace in front of you it can't find the defined option, lose the getValue() (if using var_dump) function to see if you are getting a null value, otherwise xdebug will give you a ton of hints to get around it.
I am trying to update the inventory level of a products but unfortunately not getting success.Here is my code.
I want to update product's "inventory_level" but enable to do so..
<?php
require "bigcommerce.php";
use Bigcommerce\Api\Client as Bigcommerce;
Bigcommerce::configure(array(
'store_url' => 'https://store-nos85a.mybigcommerce.com/',
'username' => 'admin',
'api_key' => '4b7c4bba19f290a728e00be6ae7133cda71f477b'
));
Bigcommerce::setCipher('RC4-SHA');
Bigcommerce::verifyPeer(false);
$product = Bigcommerce::getProduct(76);
print_r($product->skus);
foreach($product->skus as $sku)
{
if($sku->id==5)
{
$fields = array("inventory_level"=>112);
Bigcommerce::updateProduct(76,$fields);
}
echo "id : ".$sku->id;
echo " Invntory Level: ".$sku->inventory_level."<br/>";
echo " SKU : ".$sku->sku."<br/>";
}
?>
Here Bigcommerce::updateProduct(76,$field); is not working.
No need to download ALL products, why not retrieve JUST the product that has the sku you need?
GET: /api/v2/products?sku=sku-that-I'm-interested-in
parse the response for the id (that's the product ID for the product with that SKU)
Then do a PUT using that product ID.
I am trying to do the same thing (different programming language). I have a call into their support. It seems like you still must reference the product_id.
You cannot update simply by SKU. You must know the product_id. I got around this by requesting all products and loading the response into an array (product_id, sku, etc.). I then read thru the array, get the quantity from our system using the SKU, and post (PUT) the inventory_level using the associated product_id.
IMHO this is a huge oversight on their part. Who cares what the product_id is on the website?
I have asked for an enhancement that allows updating by SKU.
I have two websites for specific Store Views - English & German. Normally, I could have maintained 1 Website with two different Store Views, but it was the specific requirement of my client, to have each website for each specific store view.
Problem is I am not able to update / create different product names / descriptions, each for a product website, programmatically. I'm using this code to do it, which I found to be the same for different price:-
$combinationWebsiteWithName = array('1' => 'product name 1', '2' => 'product name 2');
foreach ($combinationWebsiteWithName as $_eachWebsiteId => $_eachProductName) {
$objWebsite = Mage::getModel('core/website')->load($_eachWebsiteId);
$storeIds = $objWebsite->getStoreIds();
$objProduct = Mage::getModel('catalog/product')
->setStoreId(end($storeIds))
->load($productId);
$objProduct->setName($_eachProductName);
$objProduct->save();
}
Can anybody please help me & find any errors in the above code?
Thanks in advance.
Eventually, I found out what was wrong in there, and so here is the answer:-
Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));
foreach ($websiteWiseProductNameArray as $_eachWebsiteId => $_eachProductName) {
$objWebsite = Mage::getModel('core/website')->load($_eachWebsiteId);
$storeIds = $objWebsite->getStoreIds();
foreach ($storeIds as $_eachStoreId) {
$objProduct = Mage::getModel('catalog/product')
->setStoreId($_eachStoreId)
->load($productId);
$objProduct->setData($targetAttrCode, $_eachProductName);
$objProduct->save();
unset($objProduct);
}
unset($storeIds, $objWebsite);
}
Last unexpected area of modification for me was setting the store ID to be that of Admin area, by using the following code: "Mage::app()->setCurrentStore(Mage::getModel('core/store')->load(Mage_Core_Model_App::ADMIN_STORE_ID));"
I'd like to create a shopping cart price rule that gives a user 10% off their order when and if they complete a process on my Magento site.
There's a method here that inserts the rule directly to the database. That's a bit invasive for my tastes.
How would I go about this using Magento methods?
As a general principle, you should be able to do anything that the Magento system itself does without writing a single line of SQL. Almost all the Magento data structures use Magento Model classes.
Run the following code somewhere to see what a salesrule/rule model looks like. This assumes you've created a single Shopping Cart Price Rule in the admin with an ID of 1
$coupon = Mage::getModel('salesrule/rule')->load(1);
var_dump($coupon->getData());
Using the dumped data as a guide, we can programatically create a model using the following
$coupon = Mage::getModel('salesrule/rule');
$coupon->setName('test coupon')
->setDescription('this is a description')
->setFromDate('2010-05-09')
->setCouponCode('CODENAME')
->setUsesPerCoupon(1)
->setUsesPerCustomer(1)
->setCustomerGroupIds(array(1)) //an array of customer grou pids
->setIsActive(1)
//serialized conditions. the following examples are empty
->setConditionsSerialized('a:6:{s:4:"type";s:32:"salesrule/rule_condition_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')
->setActionsSerialized('a:6:{s:4:"type";s:40:"salesrule/rule_condition_product_combine";s:9:"attribute";N;s:8:"operator";N;s:5:"value";s:1:"1";s:18:"is_value_processed";N;s:10:"aggregator";s:3:"all";}')
->setStopRulesProcessing(0)
->setIsAdvanced(1)
->setProductIds('')
->setSortOrder(0)
->setSimpleAction('by_percent')
->setDiscountAmount(10)
->setDiscountQty(null)
->setDiscountStep('0')
->setSimpleFreeShipping('0')
->setApplyToShipping('0')
->setIsRss(0)
->setWebsiteIds(array(1));
$coupon->save();
For anyone that's curious, the above is generated code, using the technique discussed here
Have a look at my code.It will add Action condition.
$coupon_rule = Mage::getModel('salesrule/rule');
$coupon_rule->setName($c_data[1])
->setDescription($c_data[2])
->setFromDate($fromDate)
->setToDate($toDate)
->setUsesPerCustomer(0)
->setCustomerGroupIds(array(0,1,2,3)) //an array of customer grou pids
->setIsActive(1)
->setCouponType(2)
->setCouponCode($c_data[0])
->setUsesPerCoupon(1)
//serialized conditions. the following examples are empty
->setConditionsSerialized('')
->setActionsSerialized('')
->setStopRulesProcessing(0)
->setIsAdvanced(1)
->setProductIds('')
->setSortOrder(0)
->setSimpleAction('by_percent')
->setDiscountAmount($c_data[5])
->setDiscountQty(1)
->setDiscountStep('0')
->setSimpleFreeShipping('0')
->setApplyToShipping('1')
->setIsRss(1)
->setWebsiteIds(explode(',',$c_data[6]));
$sku =$c_data[7]; // Put your product SKU here
$skuCond = Mage::getModel('salesrule/rule_condition_product')
->setType('salesrule/rule_condition_product')
->setAttribute('sku')
->setOperator('==')
->setValue($sku);
$coupon_rule->getActions()->addCondition($skuCond);
$coupon_rule->save();
echo "New Coupon was added and its ID is ".$coupon_rule->getId().'<br/>';<br/>
If you want to add Condition for shopping cart price rule then follow this example.
$sku =$c_data[7]; // Put your product SKU here
$found = Mage::getModel('salesrule/rule_condition_product_found')
->setType('salesrule/rule_condition_product_found')
->setValue(1) // 1 == FOUND
->setAggregator('all'); // match ALL conditions
$coupon_rule->getConditions()->addCondition($found);
$skuCond = Mage::getModel('salesrule/rule_condition_product')
->setType('salesrule/rule_condition_product')
->setAttribute('sku')
->setOperator('==')
->setValue($sku);
$found->addCondition($skuCond);
$coupon_rule->save();