PHP: Array > Sum all the numeric elements? - php

I found a reference in the PHP manual, but my interpretation is pretty much wrong:
$total = (sum ( array $_SESSION['list'][$item]['price'] ));
I want to sum the price of all the items in the array SESSION.
Please check the screenshot: http://img684.imageshack.us/img684/6070/20110430010324.jpg
This is the code I'm using:
<?php
session_start();
//Getting the list
$_SESSION['list'] = isset($_SESSION['list']) ? $_SESSION['list'] : array();
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$new_item = array(
'item' => $_POST['product'],
'quantity' => $_POST['quantity'],
'code' => $_POST['code'],
'price' => $products[$_POST['product']] * $_POST['quantity'],
);
$new_product = true;
foreach($_SESSION['list'] as $key => $item) {
if ($item['item'] == $new_item['item']) {
$_SESSION['list'][$key]['quantity'] += $new_item['quantity'];
$_SESSION['list'][$key]['price'] = $products[$new_item['item']] * $new_item['quantity'];
$new_product = false;
}
}
if ($new_product) {
$_SESSION['list'][] = $new_item;
}
//listing
echo "<b>SHOPPING LIST</b></br>";
foreach($_SESSION['list'] as $key => $item) {
echo 'Product .'. $key. ' '. $item['item'], ' ', $item['quantity'], ' units: ', $item['price']. '<br />';
}
echo "</br> <a href='index.html'>Return to index</a> </br>";
//Printing session
var_dump($_SESSION);
//session_destroy();
?>

$total = 0;
foreach($_SESSION['list'] as $item) {
$total += $item['price'];
}
Or if you prefer a functional style (PHP 5.3):
$total = array_reduce($_SESSION['list'], function($a, $b) {
return $a['price'] + $b['price'];
});

Related

Looping thru array for sum of one element

I have a shopping cart with three items like this:
$cart = [
1031 => [
'id' => '1031',
'model' => 'tr16',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1032 => [
'id' => '1032',
'model' => 'tr16g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1034 => [
'id' => '1034',
'model' => 'tr17g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
]
];
I have an array of IDs representing items eligible for a discount like this:
$itemIds = [
0 => [
0 => 1031
],
1 => [
0 => 1032
]
];
I loop thru each array and change the price where the ID in $cart matches ID in $itemIds by applying a 20% discount, and also add new elements. That code looks like this:
foreach($cart as &$item) {
foreach($itemIds as $ids) {
foreach($ids as $key => $value) {
if ($item['id'] == $value)
{
$item['discount_applied'] = $item['price'] * 0.2;
$item['price'] = $item['price'] * .80;
$item['promo_name'] = 'Test promo';
$item['promo_id'] = 36;
}
}
}
}
Printing the cart to the screen before and after the loop shows it's working as expected.
However, I encounter a problem when trying to loop through the modified $cart and calculate the sum of individual discounts.
My loop looks like this:
$cart['total_discount'] = 0;
foreach($cart as $item)
{
$cart['total_discount'] += $item['discount_applied'];
}
echo 'Total discount:' . $cart['total_discount'];
I expect to see the sum of discounts = 40, but instead = 60. Printing the cart to the screen before and after the loop shows that items 1031 and 1032 have a value of 20 in discount_applied and that item 1034 has no value.
Any help in identifying where I have an error or errors is appreciated.
Here's all the code if you want to copy/paste.
$cart = [
1031 => [
'id' => '1031',
'model' => 'tr16',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1032 => [
'id' => '1032',
'model' => 'tr16g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
],
1034 => [
'id' => '1034',
'model' => 'tr17g',
'price' => 100,
'discount_applied' => '',
'promo_name' => '',
'promo_id' => ''
]
];
$itemIds = [
0 => [
0 => 1031
],
1 => [
0 => 1032
]
];
echo '<h2>Cart BEFORE discount</h2>'; echo '<pre>';print_r($cart); echo '</pre>';
foreach($cart as &$item) {
foreach($itemIds as $ids) {
foreach($ids as $key => $value) {
if ($item['id'] == $value)
{
$item['discount_applied'] = $item['price'] * 0.2);
$item['price'] = $item['price'] * .80;
$item['promo_name'] = 'Test promo';
$item['promo_id'] = 36;
}
}
}
}
echo '<h2>Cart AFTER discount</h2>'; echo '<pre>';print_r($cart); echo '</pre>';
$cart['total_discount'] = 0;
foreach($cart as $item)
{
echo $item['discount_applied'] . '<br>';
$cart['total_discount'] += $item['discount_applied'];
}
echo 'Total discount:' . $cart['total_discount'];
Your use of &$item in the initial loop needs to be used in your final loop also. The loop where you adding up the discount total. You will also need to see if the discount value is a number since, in the code you posted, the 3rd item in the cart will have a blank value for the discount which will throw a non-numeric error when trying to add it to the discount total.
Your final loop modified to work:
$cart['total_discount'] = 0;
foreach($cart as &$item) {
echo '*' . $item['discount_applied'] . '*<br />'; // just to show what is or isn't there
$cart['total_discount'] += (is_numeric($item['discount_applied']) ? $item['discount_applied'] : 0);
}
echo 'Total discount:' . $cart['total_discount'];

find and loop items in array by id

I have an array what contains multiple indexes like
$arr = array(
1 => array('id' => 0,
'container' => 1
),
2 => array('id' => 1,
'container' => 1
),
3 => array('id' => 2,
'container' => 2
),
4 => array('id' => 3,
'container' => 1
)
);
How can I find and loop through all items where container is 1 and after that loop all items where container is 2 and so on..
Besides from using the wrong array assignment :. Just change it to =>.
Then just use a foreach loop:
$containers = array(1, 2);
foreach($containers as $container) {
foreach ($arr as $value) {
if($container == $value['container']) {
echo "Container: $container : ";
echo $value['id'] . '<br/>';
}
}
}
There are many ways to do this. This one re-structures/groups the array by a given key - which is feasible if you iterate over all elements anyway.
<?php
$arr = array(
1 => array('id' => 0,
'container' => 1
),
2 => array('id' => 1,
'container' => 1
),
3 => array('id' => 2,
'container' => 2
),
4 => array('id' => 3,
'container' => 1
)
);
$byContainer = groupBy($arr, 'container');
foreach($byContainer as $container=>$items) {
echo $container, "\r\n";
foreach($items as $e) {
echo ' ', $e['id'], "\r\n";
}
}
function groupBy($arr, $key) {
$result = array();
foreach($arr as $e) {
if ( !isset($result[ $e[$key] ]) ) {
$result[ $e[$key] ] = array($e);
}
else {
$result[ $e[$key] ][] = $e;
}
}
return $result;
}
<?php
$arr = array(1 => array('id'=> 0, 'container'=> 1),
2 => array('id'=> 1, 'container'=> 1),
3 => array('id'=> 2, 'container'=> 2),
4 => array('id'=> 3, 'container'=> 1));
$temp = array();
foreach ($arr as $elem) {
foreach ($elem as $k => $v) {
if ($k == 'container') {
$temp[$k][$v][] = $v;
}
}
}
print_r($temp);
?>
Working Example

Creating Configurable product programmatically in magento

I am trying to create configurable product with the attributes color and size from simple product collection.
To achieve this, I created a custom attribute named configurable_sku for respective simple products and filled with common SKU. Using this SKU we can group to create a configurable product.
I got collection from $product_sku_collection['sku'] like below,
...
array (size=387)
0 =>
array (size=2)
'conf' => string '753315' (length=6)
'simpleprodcollection' =>
array (size=1)
0 =>
array (size=10)
...
1 =>
array (size=2)
'conf' => string '753319' (length=6)
'simpleprodcollection' =>
array (size=1)
0 =>
array (size=10)
...
Below is the php script which i tried so far.
<?php
set_time_limit(0);
error_reporting(E_ALL | E_STRICT);
error_reporting(1);
ini_set('display_errors', 1);
define('D_S', DIRECTORY_SEPARATOR);
require_once 'app/Mage.php';
umask(0);
Mage::app();
if (function_exists('d') === false) {
function d($data, $die = 0, $z = 1, $msg = 1) {
echo"<br/><pre style='padding:2px 5px;background: none repeat scroll 0 0 #E04E19;clear: both;color: #FFFFFF;float: left;font-family: Times New Roman;font-style: italic;font-weight: bold;text-align: left;'>";
if ($z == 1)
Zend_Debug::dump($data);
else if ($z == 2)
var_dump($data);
else
print_r($data);
echo"</pre>";
if ($d == 1)
die();
}
}
function get_attribute_id($option, $type) {
$attributeId = Mage::getResourceModel('eav/entity_attribute')->getIdByCode('catalog_product', $type);
$attribute = Mage::getModel('catalog/resource_eav_attribute')->load($attributeId);
$attributeOptions = $attribute->getSource()->getAllOptions();
foreach ($attributeOptions as $opts_arr) {
if (strtoupper($opts_arr['label']) == strtoupper($option)) {
return $opts_arr['value'];
}
}
return FALSE;
}
$_simple_products = array();
function attributeValueExists($arg_attribute, $arg_value) {
$attribute_model = Mage::getModel('eav/entity_attribute');
$attribute_options_model = Mage::getModel('eav/entity_attribute_source_table');
$attribute_code = $attribute_model->getIdByCode('catalog__simple_product', $arg_attribute);
$attribute = $attribute_model->load($attribute_code);
$attribute_table = $attribute_options_model->setAttribute($attribute);
$options = $attribute_options_model->getAllOptions(false);
foreach ($options as $option) {
if ($option['label'] == $arg_value) {
return $option['value'];
}
}
return false;
}
//$_product = Mage::getModel('catalog/product')->load(46);
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToSelect('*');
// d($collection->getData()); exit;
$in = 0;
$product_sku_collection = array();
$product_dummy_collection = array();
foreach ($collection->getData() as $val) {
$product_dummy_collection[$in] = $val;
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('confiugrable_sku', array('eq', $val['sku']));
if (count($collection->getData()) > 0) {
$product_sku_collection['sku'][$in]['conf'] = $val['sku'];
$product_sku_collection['sku'][$in]['simpleprodcollection'] = $collection->getData();
$in++;
}
}
$color_attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', 92);
foreach ($color_attribute->getSource()->getAllOptions(true, true) as $option) {
$attributeArray[$option['value']] = $option['label'];
}
//d($attributeArray); exit;
$color_array = array();
$index = 0;
foreach ($attributeArray as $value) {
$value_index = get_attribute_id($value, 'color');
if ($value != '') {
$color_array[$index] = array(
'value_index' => $value_index,
'label' => $value,
'is_percent' => 0,
'pricing_value' => '0',
'attribute_id' => '92'
);
$index++;
}
}
//d($color_array); exit;
$size_attribute = Mage::getModel('eav/config')->getAttribute('catalog_product', 136);
foreach ($size_attribute->getSource()->getAllOptions(true, true) as $option) {
$sattributeArray[$option['value']] = $option['label'];
}
//d($attributeArray); exit;
$size_array = array();
$index = 0;
foreach ($sattributeArray as $value) {
$value_index = get_attribute_id($value, 'size');
if ($value != '') {
$size_array[$index] = array(
'value_index' => $value_index,
'label' => $value,
'is_percent' => 0,
'pricing_value' => '0',
'attribute_id' => '92'
);
$index++;
}
}
//d($size_array); exit;
// exit;
$cProduct = Mage::getModel('catalog/product');
$model = Mage::getModel('catalog/product');
$setConfigurableAttributesData = array(
'0' => array('id' => NULL, 'label' => 'Color', 'position' => NULL,
'values' => $color_array,
'attribute_id' => 92, 'attribute_code' => 'color', 'frontend_label' => 'Color',
'html_id' => 'config_super_product__attribute_0'
),
'1' => array('id' => NULL, 'label' => 'Clothing Size', 'position' => NULL,
'values' => $size_array,
'attribute_id' => 136, 'attribute_code' => 'size', 'frontend_label' => 'Clothing Size',
'html_id' => 'config_super_product__attribute_1')
);
//d(($product_sku_collection['sku'])); exit;
$index = 1;
foreach ($product_sku_collection['sku'] as $key => $value) {
$main_product_data = $model->load($value['simpleprodcollection']['0']['entity_id']);
$main_pd_name = $main_product_data->getData('name');
$setConfigurableProductsData=array();
//d($value['simpleprodcollection']['0']['entity_id']);
foreach ($value['simpleprodcollection'] as $v) {
$clab = Mage::getModel('catalog/product')->load($v['entity_id'])->getAttributeText('color');
$cvalue_index = Mage::getResourceModel('catalog/product')->getAttributeRawValue($v['entity_id'], 'color');
$slab = Mage::getModel('catalog/product')->load($v['entity_id'])->getAttributeText('size');
$svalue_index = Mage::getResourceModel('catalog/product')->getAttributeRawValue($v['entity_id'], 'size');
$setConfigurableProductsData = array(
$v['entity_id'] =>
array('0' =>
array('attribute_id' => '92', 'label' => $clab, 'value_index' => $cvalue_index, 'is_percent' => 0, 'pricing_value' => ''),
'1' =>
array('attribute_id' => '136', 'label' => $slab, 'value_index' => $svalue_index, 'is_percent' => 0, 'pricing_value' => '')
)
);
//d($setConfigurableProductsData);
}
$cProduct
->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE)
->setTaxClassId(5)
->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
->setWebsiteIds(array(1))
->setAttributeSetId(4) // You can determine this another way if you need to.
->setSku("C" . $main_product_data->getData('confiugrable_sku'))
->setName($main_product_data->getData('name'))
->setQty(25)
->setPlayer($main_product_data->getData('player'))
->setBrand($main_product_data->getData('brand'))
->setStyle($main_product_data->getData('style'))
->setShortDescription($main_product_data->getData('short_description'))
->setDescription($main_product_data->getData('description'))
->setPrice($main_product_data->getData('price'));
$cProduct->setStockData(array(
'use_config_manage_stock' => 1,
'is_in_stock' => 1,
'is_salable' => 1,
));
$cProduct->setConfigurableProductsData($setConfigurableProductsData);
$cProduct->setConfigurableAttributesData($setConfigurableAttributesData);
$cProduct->setCanSaveConfigurableAttributes(1);
try {
$cProduct->save();
//$productId = $cProduct->getId();
echo $index.") ".$cProduct->getId() . "====>" . $main_pd_name . " added\n";
} catch (Exception $e) {
echo "$main_pd_name not added\n";
echo "exception:$e";
}
$index++;
}
//****************-----------------*****************//
?>
When I run this script, it has to insert 387 configurable products with their respective simple product. But loop runs one time and stops executing, It inserts only one configurable product with their associated simple product but it has to insert all 387 configurable products.
Where have I gone wrong in this. I checked all the way to find it but could not.
Kindly give some advice on this
Finally i found it, we need to use below code inside for loop
$cProduct->save();
$cProduct->unsetData();
To make magento recognize your data as a new model again, you simply need to unset the model id
Mage::getModel('catalog/product'); this actually queries Magento registry and fetch a cached object of that model type, this style of reusing objects is known as Singleton and Magento is known for that. In cases of loops and continuous need for a new unique object, use the standard constructor call of that model. For example in case of products:
$cProduct = new Mage_Catalog_Model_Product();

PHP: Remove invalid array value?

I'm using two arrays, one is a POST string (product), and another is a predefined set of values(products).
They work together as:
$products[$_POST['product']]
This is okay if the POST value is exactly one of the following:
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
Otherwise it will pop Undefined Index messages. Since this is a SESSION, I need to somehow keep a list of items, but remove the invalid ones from the array and echo a message.
Please check the screenshot: http://img36.imageshack.us/img36/9121/20110430004019.jpg
This is the script I'm using:
<?php
session_start();
//Getting the list
$_SESSION['list'] = isset($_SESSION['list']) ? $_SESSION['list'] : array();
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$new_item = array(
'item' => $_POST['product'],
'quantity' => $_POST['quantity'],
'code' => $_POST['code'],
'price' => $products[$_POST['product']] * $_POST['quantity'],
);
$new_product = true;
foreach($_SESSION['list'] as $key => $item) {
if ($item['item'] == $new_item['item']) {
$_SESSION['list'][$key]['quantity'] += $new_item['quantity'];
$_SESSION['list'][$key]['price'] =
$products[$new_item['item']] * $new_item['quantity'];
$new_product = false;
}
}
if ($new_product) {
$_SESSION['list'][] = $new_item;
}
//listing
echo "<b>SHOPPING LIST</b></br>";
foreach($_SESSION['list'] as $key => $item) {
echo 'Product .'. $key. ' '. $item['item'], ' ',
$item['quantity'], ' units: ', $item['price']. '<br />';
}
echo "</br> <a href='index.html'>Return to index</a> </br>";
//Printing session
var_dump($_SESSION);
//session_destroy();
?>
You should use isset or array_key_exists to check whether the key exists before reading it:
if (isset($products[$_POST['product']])) {
// product in stock
} else {
// product not in stock
}
And if you use the same key for your product list in $_SESSION['list'], you don’t need to iterate the whole list to find the same product in the list:
if (isset($_SESSION['list'][$_POST['product']])) {
// update product in list
$_SESSION['list'][$_POST['product']]['quantity'] += $_POST['quantity'];
$_SESSION['list'][$_POST['product']]['price'] = $products[$_POST['product']] * $_POST['quantity'];
} else {
// add product to list
$_SESSION['list'][$_POST['product']] = array(
'item' => $_POST['product'],
'quantity' => $_POST['quantity'],
'code' => $_POST['code'],
'price' => $products[$_POST['product']] * $_POST['quantity'],
);
}
Note that this will always only add items to the list. You should add some functionality to also update and remove items. And don’t forget to validate the data before using it (e.g. so that people don’t get refund if they enter a negative quantity).
I would imagine you want to use the array_intersect_assoc function. it returns the items that are in both of your arrays.

PHP: SESSION data not being stored

This data comes from a POST form, the idea is to simply add more lines whenever a new product is added.
The current output is:
l. Banana 3 units: 150
Please take a look into the script (specially the foreach loop):
<?php
session_start();
//Getting the list
$list= $_SESSION['list'];
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$_SESSION['list'] = array(
'item' => ($_POST['product']),
'quantity' => ($_POST['quantity']),
'code' => ($_POST['code']),
);
//price
$price = $products[($_SESSION['list']['item'])] * $_SESSION['list']['quantity'];
$_SESSION['list']['price'] = $price;
//listing
echo "<b>SHOPPIGN LIST</b></br>";
foreach($_SESSION as $key => $item)
{
echo $key[''], '. ', $item['item'], ' ', $item['quantity'], ' units: ', $item['price'];
}
//Recycling list
$_SESSION['list'] = $list;
echo "</br> <a href='index.html'>Return to index</a> </br>";
//Printing session
var_dump($_SESSION);
?>
change this code:
//Saving the stuff
$_SESSION['list'] = array(
'item' => ($_POST['product']),
'quantity' => ($_POST['quantity']),
'code' => ($_POST['code']),
);
to
//Saving the stuff
$_SESSION['list'][] = array(
'item' => ($_POST['product']),
'quantity' => ($_POST['quantity']),
'code' => ($_POST['code']),
);
and remove this code:
//Recycling list
$_SESSION['list'] = $list;
Now, you'll get a new entry in $_SESSION every time you POST to the page.
Also, if you want your output to look like:
l. Banana 3 units: 150
2. Orange 5 units: 250
etc
then you'll need to change the echo in the foreach() loop from
echo $key[''] . // everything else
to just
echo ($key+1) . // everything else
Since key will be your array index starting at 0, you'll need to do a +1 every iteration, otherwise your list would look like
0. Banana 3 units: 150
1. Orange 5 units: 250
As iandouglas wrote, you are overwriting the session variable every time. The following code also fixes some undefined index issues and already existing products.
// Test POST data.
$_POST['product'] = 'Pineaple';
$_POST['quantity'] = 1;
$_POST['code'] = 1;
//Getting the list
$_SESSION['list'] = isset($_SESSION['list']) ? $_SESSION['list'] : array();
//stock
$products = array(
'Pineaple' => 500, 'Banana' => 50, 'Mango' => 150,
'Milk' => 500, 'Coffe' => 1200, 'Butter' => 300,
'Bread' => 450, 'Juice' => 780, 'Peanuts' => 800,
'Yogurt' => 450, 'Beer' => 550, 'Wine' => 2500,
);
//Saving the stuff
$new_item = array(
'item' => $_POST['product'],
'quantity' => $_POST['quantity'],
'code' => $_POST['code'],
'price' => $products[$_POST['product']] * $_POST['quantity'],
);
$new_product = true;
foreach($_SESSION['list'] as $key => $item) {
if ($item['item'] == $new_item['item']) {
$_SESSION['list'][$key]['quantity'] += $new_item['quantity'];
$_SESSION['list'][$key]['price'] = $products[$new_item['item']] * $new_item['quantity'];
$new_product = false;
}
}
if ($new_product) {
$_SESSION['list'][] = $new_item;
}
//listing
echo "<b>SHOPPIGN LIST</b></br>";
foreach($_SESSION['list'] as $key => $item) {
echo 'key '. $key. ' '. $item['item'], ' ', $item['quantity'], ' units: ', $item['price']. '<br />';
}

Categories