I have a shopping cart, which works just fine, but I would like to store type of goods (for example color, size, etc.).
Here is a function that gets items from shopping cart
public static function getCart() {
if((isset($_SESSION['cart'])) && count($_SESSION['cart'])>0) {
$ids = "";
foreach($_SESSION['cart'] as $id => $quantity) {
$ids = $ids . $id . ",";
}
$ids = rtrim($ids, ',');
$dotaz = dibi::fetchAll("SELECT * FROM eshop_products WHERE idProduct IN ({$ids})");
return $dotaz;
} else {
//do nothing
}
}
And function that adds items to shopping cart
public static function addToCart($data) {
$id = $data['id'];
$quantity = $data['qty'];
$varianta = $data['varianty']; //THIS IS WHAT I NEED TO ADD TO SESSION ARRAY
if(!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
if(isset($_SESSION['cart'][$id])) {
$_SESSION['cart'][$id] += $quantity;
} else {
$_SESSION['cart'][$id] = $quantity;
}
}
Is there some easy way to do that? I googled some tutorials, but still no success.
Thank you.
Maybe this is a hint for you:
$id = $data['id'];
$quantity = $data['qty'];
$varianta = $data['varianty']; //THIS IS WHAT I NEED TO ADD TO SESSION ARRAY
$cart = array();
array_push($cart, array(
'id' => $id,
'quantity' => $quantity,
'varianta' => $varianta
));
Related
What i am trying to do is save a new variation but when saving it, it throws an error
Call to a member function get_name() on string;
The variations are being created but without any attribute value.
public static function create_product_variants($id,$product,$variant_data){
for($i=0; $i< count($variant_data); $i++){
$variant = new WC_Product_Variation();
$variant->set_parent_id($id);
foreach($variant_data[$i] as $key => $value){
if($key == 'attribute_name'){
$attribute_name = $value;
}
if($key == 'variant'){
if(gettype($value) == 'string'){
$variants = [$value];
}else{
$variants = $value;
}
}
}
if(count($variants) == count($attribute_name)){
$variant_attributes = array();
for($j=0; $j< count($variants); $j++){
$variant_attributes[$attribute_name[$j]] = $variants[$j];
}
$variant->set_attributes($variant_attributes);
}
$id = $variant->save();
}
}
The data passing through $variant_data is like:
[
{
attribute_name: ["Color","Size"]
price: "10"
quantity: "20"
variant: ["red","24"]
}
]
$id is product_id
There are some complications and mistakes in your code. Instead try the following revisited code:
public static function create_product_variants( $id, $product, $data ){
foreach( $data as $variation_data ){
if( isset($variation_data['attribute_name']) && isset($variation_data['variant']) ){
$variation = new WC_Product_Variation();
$variation->set_parent_id($id); // Set parent ID
$variation->set_regular_price($variation_data['price']); // Set price
$variation->set_price($variation_data['price']); // Set price
// Enable and set stock
if ( isset($variation_data['quantity']) ) {
$variation->set_manage_stock(true);
$variation->set_stock_quantity($variation_data['quantity']);
$variation->set_stock_status('instock');
}
$attributes = array(); // Initializing
$attribute_names = (array) $variation_data['attribute_name'];
$attribute_terms = (array) $variation_data['variant'];
// Formatting attributes data array
foreach( $attribute_names as $key => $attribute_name ){
$attributes[sanitize_title($attribute_name)] = $attribute_terms[$key];
}
$variation->set_attributes($attributes); // Set attributes
$variation_id = $variation->save(); // Save to database (return the variation Id)
}
}
}
It should better work.
The variations will be created/saved, the the method get_name() should not throw any error this time.
Do it simple like
public static function create_product_variants($id,$product,$variant_data){
foreach ($variant_data as $object){
$variant = new WC_Product_Variation();
$variant->set_parent_id($product->get_id());
$attributes = array_combine($object->attribute_name, $object->variant)
$variant->set_attributes($attributes);
$variant->save();
}
}
if the object is
[
{
attribute_name: ["Color","Size"]
price: "10"
quantity: "20"
variant: ["red","24"]
}
]
Im not pro in programming
i have a foreach loop that gets the values from a form calculating the total and subtotal
public function salecal()
{
if ($this->input->post())
{
$i = 0;
$data = array();
$subtotal = 0;
foreach($this->input->post('pname') as $d){
$data[] = array(
'pid' => $this->input->post('pid[]')[$i],
'pname' => $this->input->post('pname[]')[$i],
'quantity' => $this->input->post('qty[]')[$i],
);
foreach ($data as $entry) {
$qty = $entry['quantity'];
$pid = $entry['pid'];
$proname = $entry ['pname'];
}
$value = $this->insert_model->get_price($pid); ///pasing the product id to get the the price from database
foreach ($value->result() as $row)
{
$price = $row->price;
}
$total = $price * $qty; ////Total calculation
$subtotal = $subtotal + $total;/////Sub Total Calculation
$i++;
}
$result = compact("proname", "price", "qty", "total","i", "subtotal");
$this->load->view("bill", $result);
}
}
when i run this code im getting only the finally entered products details but the subtotal is correct
but the data inserting form is dynamic
what i want as result is
user will insert several or one item with quantity
data should be calculated and pass the calculated values to view
but currently im getting it only for the last inserted data please help me how to catch all the datas that user insert to form and how to pass them to view
Because your overwriting the variables consequently so it's passing last overwrite value only . you should make array for each one
This how you need to send all data to view using array
<?php
public function salecal()
{
if ($this->input->post())
{
$i = 0;
$data = array();
$subtotal = 0;
$final_array_collection =array();
foreach($this->input->post('pname') as $d){
$total =0; //reset the total to zero for each product
$pid = $this->input->post('pid[]')[$i];
$pname = $this->input->post('pname[]')[$i];
$quantity = $this->input->post('qty[]')[$i];
$value = $this->insert_model->get_price($pid); ///pasing the product id to get the the price from database
foreach ($value->result() as $row)
{
$price = $row->price;
}
$total = $price * $quantity; ////Total calculation
$subtotal = $subtotal + $total;/////Sub Total Calculation
$final_array_collection[] =array("proname"=>$pname, "price"=>$price, "qty"=>$quantity, "total"=>$total,"i"=>$i, "subtotal"=> $subtotal);
$i++;
}
$result = compact("final_array_collection");
$this->load->view("bill", $result);
}
}
?>
I have a simple problem. Lets say I have an array
Array
0
product_id 233
slug "zotac-geforce-gtx-1070-amp-extreme-edition-8gb-zt-p10700b-10p"
1
product_id 227
slug "zotac-geforce-gtx-1060-mini-6gb-gddr5-zt-p10600a-10l"
2
product_id 233
slug "zotac-geforce-gtx-1070-amp-extreme-edition-8gb-zt-p10700b-10p"
Now if you see there are two products having same product_id! I don't want that I am trying to get this array filtered from duplicate products
This is what I tried but it doesn't work
$temp_products = array();
foreach($products as $product)
{
if(count($temp_products) > 0)
{
foreach($temp_products as $temp_product)
{
if($temp_product['product_id'] != $product['product_id'])
{
$temp_products[] = $product;
}
}
}
else
{
$temp_products[] = $product;
}
}
It returns the same array as the original one. and $products is the main array having the data.
Try this! But I would definitely suggest using array_filter or array_unique will post an example later. Try this.
$temp_products = array();
$count = 0;
foreach($products as $product)
{
if(count($temp_products) > 0)
{
//foreach($temp_products as $temp_product)
//{
if($temp_products[$count]['product_id'] != $product['product_id'])
{
$temp_products[] = $product;
}
//}
}
else
{
$temp_products[] = $product;
}
}
Using array_unqiue
foreach($products as $product)
{
$temp_products[] = $product;
}
dd(array_unique($temp_products));
Another way would be to use a helper array to keep track of already present ids.
$temp_products = array();
$already_present = array();
foreach($products as $product)
{
$id = $product['product_id'];
if ( isset($already_present[ $id ] ) ) continue;
$temp_products[] = $product;
$already_present[ $id ] = '';
}
$products = $temp_products;
I have an issue when I'm trying to set a data into my item:
add_filter('woocommerce_add_cart_item_data', '_add_custom_item_data', 10, 2);
add_filter('woocommerce_get_cart_item_from_session', '_get_cart_item_from_session', 10, 2);
function _add_custom_item_data($cart_item_data, $product_id){
if(!empty($cart_item_data)){
$cart_item_data['custom_field'] = 'aaaa';
}
return $cart_item_data;
}
function _get_cart_item_from_session($cart_item, $values){
if (isset($values['custom_field'])) {
$cart_item['custom_field'] = $values['custom_field'];
}
return $cart_item;
}
when I use:
$woocommerce->cart->add_to_cart($id,'1','','',array('_my_data','000000000000000000000000000000'));
the _add_custom_item_data function is executed as well and I have the _my_data variable.
but i'm try to get the variable with my product:
$items = $woocommerce->cart->get_cart();
foreach($items as $item){
echo $woocommerce->cart->get_item_data( $item ) . "<br>";
}
I didn't see my variable...
Any idea?
At last function try following to get data
<?php
$cart = $woocommerce->cart->get_cart();
$items = 0;
$total = 0;
foreach ($cart as $p) {
$total += $p['line_total'];
$items += $p['quantity'];
}
echo $items;
echo $total;
?>
instead of assigning data directly to an index you should assign it to product_meta first, for example, you can try this
$item_meta['your_key] = 'your_value';
$cart_item_data ['product_meta'] = array('meta_data' => $item_meta);
I need to calculate a sub total of the items in a shopping cart. It stores the items added to the cart as an array of the product IDs in a session variable.
So to start with I need to use the ID in the cart array to pull the product information from the database (name, price etc.) and then add the prices of all the items in the cart, of which there could be more than one of the same product.
My test cart should have a total price of 96,049.98 but my code is returning a total price of 18. I don't know where it's getting that from.
Here is the code:
function subTotal() {
global $db;
global $table_prefix;
$table = $table_prefix . "products";
foreach($_SESSION['cart'] as $item) {
$sql = $db->prepare("SELECT * FROM $table WHERE id = :id");
$sql->bindParam(":id", $item[0]);
$sql->execute();
$amount = 0;
$product = $sql->fetch(PDO::FETCH_ASSOC);
foreach($product as $price) {
$amount += $price['price'];
}
}
return $amount;
}
You are restarting the value $amount to 0 per iteration.
Try initializating it at the top:
function subTotal() {
global $db;
global $table_prefix;
$table = $table_prefix . "products";
$amount = 0; //MOVED HERE at the top
foreach($_SESSION['cart'] as $item) {
$sql = $db->prepare("SELECT * FROM $table WHERE id = :id");
$sql->bindParam(":id", $item[0]);
$sql->execute();
$product = $sql->fetch(PDO::FETCH_ASSOC);
foreach($product as $price) {
$amount += $price['price'];
}
}
return $amount;
}
Just take out $amount = 0 out of the loop. As it's getting reset on each product loop.
$amount = 0;
foreach($_SESSION['cart'] as $item) {
$sql = $db->prepare("SELECT * FROM $table WHERE id = :id");
$sql->bindParam(":id", $item[0]);
$sql->execute();
$product = $sql->fetch(PDO::FETCH_ASSOC);
foreach($product as $price) {
$amount += $price['price'];
}
}
As I mentioned in my comment: In case you are able to change the way your shopping cart stores items, you could refactor your code to something like this:
function subTotal() {
$db = $GLOBALS['db'];
$table_prefix = $GLOBALS['table_prefix'];
$table = $table_prefix . "products";
$totalPrice = 0;
// assuming that you actually store ($id => $amount) pairs
$ids = join(',', array_map('intval', array_keys($_SESSION['cart'])));
$stmt = $db->prepare("SELECT id, price FROM $table WHERE id IN ($ids)");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$amount = $_SESSION['cart'][$row['id']];
$totalPrice += $amount * $row['price'];
}
return $totalPrice;
}
If would assume, that your shopping cart variable would contain something like this:
array(
4 => 1, // 1 item with ID 4
22 => 8 // 8 items with ID 22
)