I know this is a dump/basic question but I'm stuck and could use some help being a newbie.
What I'm Trying to Achieve: I want to have a foreach loop to get all of the product names in my users cart.
Problem: The foreach loop stops after the second iteration (if there are three things in the cart and I dump, only 2 are shown(the first and second)).
I know what a foreach loop does. I think my problem lays in my variable names but I tried messin around with them to no avail.
if (is_null($cart) || $cart->getSubmitted(true)) {
$cart = new UserCart();
// since new cart no need to check for duplicate product quantity
// add product to cart
$this->addFlash('notice', 'Creating a new cart because one didnt exist for the user before.');
}
else {
$quantity = new Quantity();
//If the cart is set
$getProductsInCurrentUsersCart = $cart->getQuantities(); //All Products In Users Cart (ARRAY COLLECTION/PERSITENT COLLECTION)
foreach ($getProductsInCurrentUsersCart as $key => $value) {
dump($getProductsInCurrentUsersCart);
$getProductsInCurrentUsersCart = $value->getProduct()->getName(); //SHOULD BE ALL PRODUCTS IN CART
if ($getProductsInCurrentUsersCart === $quantity->setProduct($productBeingAddedToCart)->getProduct()->getName()) {
$this->addFlash('notice', 'Comparission was TRUE.');
$quantity->setQuantity($quantity->getQuantity() + 1);
}
else {
$quantity->setQuantity(1);
$quantity->setProduct($productBeingAddedToCart);
$this->addFlash('notice', 'Comparisson was FALSE.');
} //ENDS IF/ELSE
} //EXECUTING ONCE??????????
$cart->setTimestamp(new \DateTime()); // Set Time Product was Added
// $quantity->setQuantity(1); // Set Quantity Purchased
$cart->setSubmitted(false); // Set Submitted
$cart->setUser($this->getUser()); // Sets the User ONCE
$cart->addQuantity($quantity); // Add Quantity ONCE
$quantity->setUserCart($cart); // Create a UserCart ONCE
$em->persist($productBeingAddedToCart);
$em->persist($cart);
$em->persist($quantity);
$em->flush();
$this->addFlash('notice', 'The product: '.$productBeingAddedToCart->getName().' has been added to the cart!');
}
Any help is really appreciated!
$getProductsInCurrentUsersCart = $value->getProduct()->getName();
Here you are redefining the list variable inside the loop. Try with $getProductsInCurrentUsersCart2 and also change it below this line. See if that solves it or not. Then come up with a better name :)
Related
I trying to learn PS and i want to simple update all Prestsahop products state by external script.
I have something like this to disable all products by the supplier (example):
<?php
include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');
$default_lang = Configuration::get('PS_LANG_DEFAULT');
$product = new Product();
if ($product->id_supplier = 2) {
$product->active = 0;
$product->update();
}
But it failed throwing PrestaShopDatabaseException
It seems that you create a new product and don't fill the required fields. If you want to change the existing product you need to set its id during a product object creation.
So your code should be like
$product = new Product($id_product, true, $default_lang); // if you want to get certain language, if ont skip the last parameter
if ($product->id_supplier = 2) {
$product->active = 0;
$product->update();
}
as i understood you want to disable all products for a specific supplier
first you want to get list of all product ids from table ps_product in database. then instantiate a product object by each id_product and disable it if it has the id_supplier condition that you mentioned
require(dirname(__FILE__).'/../config/config.inc.php');
// getting list of product_id
$product_ids = Db::getInstance()->executeS('select id_product from ps_product');
foreach($product_ids as $item) {
$product = new Product($item['id_product']);
if ($product->id_supplier == 2) {
$product->active = false;
$product->update();
}
}
I am struggling with a weird situation here with arrays in PHP. I am trying to create a simple cart using a session variable.
Problem:
When the cart is empty, the program creates a new product with the itemid and qty variables when a product is added to cart (as required). It also does same when other new products are added.
It also is able to update the quantity of products if added again (as required).
But the problem here is it never finds the 1st product I add, so whenever I add that product again, it stacks the product every time and does not update the quantity of the product. Whereas for other products other than 1st, it acts as expected.
eg. when product A is added to empty cart, it adds itemid as A and qty = 1. When the product A is added again to an empty cart, it adds the itemid as A and qty=1 again (does not do qty=2). If I add B, C or others repeatedly it updates their qty as required
<?php
public function addinTable($id){
$this->loadModel('Carts');
/////////inserting into the cart table//////////7
$item = $this->Products->get($id);
$session = $this->request->session();
$allProducts = $session->read('Cart');
if(null!=$allProducts){
echo "<br>if(allProducts is NOT EMPTY)<br>";
if(array_search($id,array_column($allProducts, 'itemid'))){
//if the id is already in list
echo "<br><b>ITEM Is IN the list already</b>";
$key = array_search($id,array_column($allProducts, 'itemid'));
echo "<br> key is ", $key;
$newqty = debug($allProducts[$key]['qty']);
echo "<br> new qty +1 = ".$newqty+=1;
debug($allProducts[$key]['qty']++);
$session->write('Cart',$allProducts);
debug( $session->read('Cart'));
}
else{
echo"<br><b>The id is not found but cart is not empty</b>";
$allProducts[] = array('itemid'=>$id,
'qty' => 1
);
debug( $session->read('Cart'));
}
}
else{///////////if cart is empty at first
echo"<br><b>The cart is empty</b>";
$allProducts[] = array('itemid'=>$id,'qty' => 1);
debug($allProducts[0]);
debug($allProducts);
debug($allProducts[0]['itemid']);
// if(array_search($id,array_column($allProducts, 'itemid'))==true){echo "hello";}
$session->write('Cart',$allProducts);
debug($session->read('Cart'));
}
$session->write('Cart',$allProducts);//save the item
}
?>
array_search() returns the index, which is 0 for the first product. 0 evaluates to false.
You need a comparison against false here.
Change
if(array_search($id,array_column($allProducts, 'itemid'))) { //...
to
if(array_search($id,array_column($allProducts, 'itemid')) !== false) { //...
here's a fiddle that demonstrates this change: https://3v4l.org/m62Ya
As above, I've got a strange issue where every other product I add isn't added to the cart or quote in Magento.
It's repeatable, in that I can add one product, then the next one doesn't add (but I do get a status messaging saying it was added), and then the next done after that adds as it should do.
It's not specific to a product, as if I add the same product a second time it will add as expected.
The only thing we have that's a little different is an observer called on the sales_quote_add_item event, but that's just changing the pricing:
public function update_book_price(Varien_Event_Observer $observer) {
//get the admin session
Mage::getSingleton('core/session', array('name'=>'adminhtml'));
if (!$quoteitem = $observer->getQuoteItem()){
$quoteitem = $observer->getItem();
}
if (!$item = $observer->getEvent()->getQuoteItem()){
$item = $quoteitem;
}
$quote = $item->getQuote();
$product = $item->getProduct();
$price = Mage::helper('users')->getCustomerProductPrice(false,Mage::getModel('catalog/product')->load($product['product_id']),false,true,$_POST['qtys'][$product['product_id']]);
echo "Price : $price \n";
//print_r($price);
$price = $price;
if(!$quoteitem->setOriginalCustomPrice($price)) {
echo "Couldn't set price";
}
else {
echo "price updated, save";
try {
$quoteitem->getProduct()->setIsSuperMode(true);
var_dump($quoteitem->save());
}catch(Exception $e){
echo $e->getMessage() . "\n";
}
}
return $this;
}
I've checked at a DB level, and the missing items are not even in the DB - sales_flat_quote_item has no record of them, but the 'working' items are in as normal.
Has anyone experienced anything like this before, or can anyone suggest where I might start investigating? Thanks!
You don't have to save quote item after changing price.
Delete var_dump($quoteitem->save()); and try again.
In Prestashop, I've created a custom form where I show a list with all products and the user can fill the corresponding quantities. By submitting the form, I clear the cart and fill it with the new values and finally redirect to the checkout page.
Everything's working fine, but only when the cart already exists. In a case of an empty cart (cart_id==null), I cannot add the products. I tried with several ways to create a $cart but I didn't manage to do so.
I don't get any exceptions, the code is executed without errors, it's just that at the end, in the checkout page, the cart remains empty; I repeat, only when the cart was already empty. In the case of a cart with products in it, then the process is just perfect!
I would appreciate some help on this.
Here is my small controller that gets the products and quantities from the form and adds them in the cart:
include('../../config/config.inc.php');
include('../../header.php');
// Filling the array of products
$products = array();
foreach ($_POST as $key => $value)
if (substr($key, 0, 9) === 'quantity_')
$products[substr($key, 9)] = $value;
// First of all, we remove all products
$prods = $cart->getProducts();
foreach ($prods as $prod)
$cart->deleteProduct($prod['id_product']);
// Adding the new products
foreach ($products as $product_id => $quantity)
if ($quantity > 0)
$cart->updateQty($quantity, $product_id);
// Redirecting to the checkout page.
header("Location: " . $_POST['redirect']);
exit();`
Thank you in advance!
I had the same problem with Prestashop not correctly creating a new cart upon calling the CartCore in many different ways - neither context or direct calls did work out.
Found this gem from someone else over here:
// get cart id if exists
if ($this->context->cookie->id_cart)
{
$cart = new Cart($this->context->cookie->id_cart);
}
// create new cart if needed
if (!isset($cart) OR !$cart->id)
{
$cart = new Cart();
$cart->id_customer = (int)($this->context->cookie->id_customer);
$cart->id_address_delivery = (int) (Address::getFirstCustomerAddressId($cart->id_customer));
$cart->id_address_invoice = $cart->id_address_delivery;
$cart->id_lang = (int)($this->context->cookie->id_lang);
$cart->id_currency = (int)($this->context->cookie->id_currency);
$cart->id_carrier = 1;
$cart->recyclable = 0;
$cart->gift = 0;
$cart->add();
$this->context->cookie->id_cart = (int)($cart->id);
$cart->update();
}
This is working for me now. As you see it goes a little more in depth than just asking the context to retrieve or create a new cart. hth.
You probably need to include this line when you are outside of a class
$context = Context::getContext();
And then add a cart variable that defines cart attributes ( in ur case assigns a id )
$cart = $context->cart; // gets the cart id or creates a new one
Should work fine now
BR's ( dont forget to accept the answer if it helps you :) )
As a complement to previous posts.
If you set that configuration : Configuration::updateValue('PS_CART_FOLLOWING', 1) (display the last cart of the customer instead of creating a new one each time).
You will always get the cart id $this->context->cart->id at NULL when trying to create a new cart at the customer's first log in (after creating a new account) using the following code:
if (is_null($this->context->cart)) {
$this->context->cart =
new Cart($this->context->cookie->id_cart);
}
I manage to solve the problem by adding some code to after the invalid cart creation.
/**
* Manage the possible errors when trying to create
* a new cart for a customer.
*
* The new cart is saved in the current context ($this->context->cart).
*/
private function createCart()
{
if (is_null($this->context->cart)) {
$this->context->cart =
new Cart($this->context->cookie->id_cart);
}
if (is_null($this->context->cart->id_lang)) {
$this->context->cart->id_lang = $this->context->cookie->id_lang;
}
if (is_null($this->context->cart->id_currency)) {
$this->context->cart->id_currency = $this->context->cookie->id_currency;
}
if (is_null($this->context->cart->id_customer)) {
$this->context->cart->id_customer = $this->context->cookie->id_customer;
}
if (is_null($this->context->cart->id_guest)) {
if (empty($this->context->cookie->id_guest)){
$this->context->cookie->__set(
'id_guest',
Guest::getFromCustomer($this->context->cookie->id_customer)
);
}
$this->context->cart->id_guest = $this->context->cookie->id_guest;
}
if (is_null($this->context->cart->id)) {
$this->context->cart->add();
$this->context->cookie->__set('id_cart', $this->context->cart->id);
}
}
After initializing the cart that way, I'm now able to add products to the cart with no problem.
Good success everyone
The shopping cart I am building only seems to update the quantity for the first element of the array. So for example the first item in my shopping cart would have a quantity of 1 and then when I added another quantity of 2 from the products page the total then changes to 3 which is what I want. If I however repeat these steps for another item it will add them into the array separately rather than grouping them together
if(isset($_GET['add'])){
foreach ($_SESSION['cart'] as $key => $item){
if ($item['id'] == $itemID) {
$newQuan = $item['quantity'] + $quantity;
unset($_SESSION['cart'][$key]);
$_SESSION['cart'][] = array("id" => $itemID,"quantity" => $newQuan);
header('Location:xxx');//stops user contsanlty adding on refresh
exit;
}
else{
$_SESSION['cart'][] = array("id" => $itemID,"quantity" => $quantity);
header('xxx');//stops user contsanlty adding on refresh
exit;
}
}
}
Can anyone help me out as to why the first element gets updated only ?
Your problem is the else-case in the foreach-loop. The very first item gets checked by the if and then - when the first item does not match - the else case activates and adds the new item.
else{
$_SESSION['cart'][] = array("id" => $itemID,"quantity" => $quantity);
header('xxx');//stops user contsanlty adding on refresh
exit;
}
What you would want to do, is to check the whole cart and then - if the article was not found - add it to the cart. For this I would suggest to use a variable for checking whether you found the entry inside the loop. For inspiration I inserted the code below. There are only minor changes needed: Add the found-variable and initialize it (to not found), set the variable to found in your if-case and check whether the variable is set after quitting the foreach-loop (which if it is not, you know for sure that you want to add the item to your cart).
$foundMyArticle = 0;
foreach ($_SESSION['cart'] as $key => $item){
if ($item['id'] == $itemID) {
$foundMyArticle = 1;
... THE OTHER CODE
} //end of the foreach
if($foundMyArticle == 0)
{ //COPY THE CODE FROM THE ELSE-CASE HERE }
I've not tested it, but this could be a little simpler:
if(isset($_GET['add']))
{
if(!isset($_SESSION['cart'])) $_SESSION['cart'] = array();
if(!isset($_SESSION['cart'][$itemID]))
{
$_SESSION['cart'][] = array('id' => $itemID, 'quantity' => $quantity);
}
else
{
$_SESSION['cart'][$itemID]['quantity'] += $quantity;
}
}
Firstly, the question and the code don't seem really clear enough, but i'll try my best to give suggestions i think might help (I'll make some assumptions).
Where are these variables coming from?
$itemID, $quantity
Going on the assumption that they're coming in the $_GET, I'd say it would be better to save your cart information like so:
$itemCartIndex = strval($itemID);
//convert the integer item id to a string value -- or leave as string if already a string
$currentQuantity = (isset($_SESSION["cart"][$itemCartIndex]))? intval($_SESSION["cart"][$itemCartIndex]["quantity"]):0;
//set it by default if the index does not exist in the cart already
$currentQuantity += $quantity;
//update the quantity for this particular item
$_SESSION["cart"][$itemCartIndex] = array("quantity"=>$currentQuantity,...,"price"=>12.56);
//set up the index for this item -- this makes it easy to remove an item from the cart
//as easy as unset($_SESSION["cart"][$itemCartIndex]
With that done, displaying/presenting the cart back to the owner is trivial.
Good luck