How to exclude data from an array? - php

On a product page I want to show 4 other products selected randomly, but never the product that is already being displayed. The product id of the displayed one is $_product->getId() and all the products go into a $result[] array like this:
foreach($collection as $product){
$result[]=$product->getId();
}
I'm using $need = array_rand($result, 4); to get the ids of the 4 random products, but it might include the id of the product on display. How do I exclude $_product->getId() from the $need[] array? Thank you.

Don't put id of the product you don't want to show into $result:
$currentProductId = $_product->getId();
foreach ($collection as $product) {
if ($product->getId() != $currentProductId) $result[] = $product->getId();
}

Is it acceptable to just not put the current product ID in the array?
foreach($collection as $product) {
if( $product != $_product) $result[] = $product->getId();
}

You might generate your random numbers first, like so:
$rands = array();
while ($monkey == false){
$banana = rand(0,4);
if (in_array($banana, $rands) && $banana != $_product->getId()){ $rands[] = $banana; }
if (sizeOf($rands) == 4){
$monkey = true;
}
}
Then you could pipe them through your product grabber. Obviously, you'd need to figure out the bounds for rand yourself but you know more about your app than I do. Picking your numbers first is much cheaper computationally than pulling records and THEN checking to make sure that they're unique.
Of course, if this is database-backed, you could solve it much more elegantly by writing a new query.

If you use the product id as the index $result[] in result, you can remove the current product from the $result array with unset() before making the call to array_rand() like so:
foreach($collection as $product){
$result[$product->getId()] = $product->getId();
}
unset($result[$_product->getId()]);
$need = array_rand($result, 4);
This approach saves you from having to use the values in $need to look up the product id in your $result[] array, since the values in $need will be your product ids.

Related

How to create stock management in PHP

I want to create stock management system in my website using php. It sounds like 'balancing' stock in database with amount of items that will purchased. If the item's amount is more than the item's stock, the website should displaying an alert. So, the amount of item cannot be more than the item's stock in database.
Here's my code :
$stock = array();
foreach ($_SESSION['cart'] as $k => $v) {
$sql = mysql_query("SELECT book_stock FROM book WHERE book_title='$k'");
while ($row = mysql_fetch_assoc($sql)) {
$stock[] = $row['book_stock'];
}
if ($stock < $v) {
echo "Stock less than the amount";
}
else {
echo "Stock sufficient";
}
}
The $k variable store the item's name in the session cart. And the $v variable store the item's amount in the transaction.
The item's amount will be increased if the visitor click 'Increase' button.
But if i increase the item's amount, the if and else logic like "isn't working". No matter how much the item's amount is added, the if and else logic keep print "Stock Sufficient".
Can anyone help me to solve this? Thanks in advance :)
Edit :
The variable in original code is in indonesian. So when i'm typing this post, i'm editing the variables too here. So if the variables is different, i'm just forget to rename it. So i edit the script again :)
$sql = mysql_query("SELECT book_stock FROM ooku WHERE book_title='$k'");
I am assuming that your query will return unique book (single book) stock detail, you have to use $stok instead of $stok[] Array
while ($row = mysql_fetch_assoc($sql)) {
$stok = $row['book_stock'];
}

Fill Values in multidimensional Array (PHP)

I've got a small problem. I'm working on a little package/product-list.
If you're watching a Package, my website should show you which products are in there.
If a product is more than one time in it, the array should be deleted and the value of the leftover array should be + 1 (each deleted array).
So here's my code:
// $products_in_package has all products in it
// First of all, the products come from a db and don't have a count
// So i first give them a count of 1
foreach ($products_in_package as $product => $value) {
$products_in_package[$product]['count'] = intval(1);
}
foreach ($products_in_package as $product) {
$id_to_find = intval($product['ID']);
$product_count = intval($product['count']);
$found_id = 0;
// Now I try to find any ident products
// If found and over 1 time (beacouse he finds the first too of course)
// Then delete this array and count up the products count
for ($i=0; $i <= count($products_in_package); $i++) {
if(intval($products_in_package[$i]['ID']) === $id_to_find){
$found_id++;
if($found_id > 1){
$product_count = $product_count + 1;
$product['count'] = $product_count;
unset($products_in_package[$i]);
array_merge($products_in_package);
while($i > $products_in_package){
$i = 0;
}
}
}
}
}
What I'm getting is the correct multidimensional array but the count is still 1.
What's wrong with the code?
Everytime I try to log the code i'm getting the right integer. (No, I already tried to delete the chache)
But if I log the array out of the loops, I get always the count of 1.
$product is a copy of the array element, so when you do $product['count'] = $product_count you're assigning to a copy, not the original array.
You can fix this by using a reference in the foreach:
foreach ($products_in_package as &$product) {

Removing an item from an array during a foreach loop

I have the following foreach being performed in PHP.
What I would like to do is instead of the $invalid_ids[] = $product_id; building and then looping around that, I would instead like to remove the entry from array that is being looped around as I'm looping around it..
For example:
If the current $product_id fails any of the test, delete the item from the $current_list array and proceed to the next iteration of the foreach loop.
I tried to do an unset($product_id) while the foreach loop header looked like this: foreach ($current_list as &$product_id) {, but the item item is still in the array.
Does anyone have any ideas on how I can go about doing this?
foreach ($current_list as $product_id) {
// Test 1 - Is the product still active?
// How to test? - Search for a product in the (only active) products table
$valid = $db->Execute("SELECT * FROM " . TABLE_PRODUCTS . " WHERE products_id = " . $product_id . " AND products_status = 1");
// Our line to check if this is okay.
if ($valid->RecordCount <= 0) { // We didn't find an active item.
$invalid_ids[] = $product_id;
}
// Test 2 - Is the product sold out?
if ($valid->fields['products_quantity'] <= 0 and STOCK_ALLOW_CHECKOUT == "false") { // We found a sold out item and it is not okay to checkout.
$invalid_ids[] = $product_id;
}
// Test 3 - Does the product have an image?
if (empty($valid->fields['products_image'])) { // Self explanatory.
$invalid_ids[] = $product_id;
}
}
$product_id isn't the actual data in the array, it's a copy of it. You would need to unset the item from $current_list.
I'm don't know how $current_list is stored, but something like unset($current_list['current_item'] would do the trick. You can use key to select the current_item key in the array.
A similar way of iterating the Array, where you can get the array key, from the PHP key docs...
while ($fruit_name = current($array)) {
if ($fruit_name == 'apple') {
echo key($array).'<br />';
}
next($array);
}
Untested, but something like this...
while ($product_id = current($current_list)) {
// Do your checks on $product_id, and if it needs deleting...
$keyToDelete = key($array);
unset($current_list[$keyToDelete]);
next($current_list);
}
I think this simple code may help you
let's say we have an array of integers and we want to remove all the items that are equal to "2" inside of the foreach loop
$array = [1,2,1,2,1,2,1];
foreach ($array as $key => $value)
{
if($value==2)
unset($array[$key]);
}
var_dump($array);
this shows the following result
array (size=4)
0 => int 1
2 => int 1
4 => int 1
6 => int 1

How do I get CustomerName from an Order?

I had added a custom option Complete in action dropdown(sales->orders). It's working fine and order status changes to complete successfully.
I am integrating all orders with Salesforce. I have need of all of order details by orderid. Item details and grand total is fetched successfully.
Can anyone please help to fetch Customer name and his/her company name how submitted order. Below is my complete code to fetch order details:
$order = Mage::getModel('sales/order')->load($orderId);
$items = $order->getAllItems();
$_totalData = $order->getData();
$_grand = $_totalData['grand_total'];
$custname = $_totalData->getCustomerName();
$itemcount=count($items);
foreach ($items as $itemId => $item)
{
$sObject2->Item_name__c = $item->getName();
$sObject2->Unit_price__c = $item->getPrice();
$sObject2->Sku__c = $item->getSku();
$sObject2->Quantity__c = $item->getQtyToInvoice();
}
try this
$order->getCustomerName()
You probably don't need to cast $order->getData() to a new variable. This will only serve to chew up memory, especially since there is only one element you need from that data, which can be retrieved with a less intensive method.
Instead, try it this way:
$order = Mage::getModel('sales/order')->load($orderId);
$_grand = $order->getGrandTotal();
$custname = $order->getCustomerName();
foreach ($order->getAllItems() as $itemId => $item)
{
// Do stuff
}
if $order->getCustomerName() doesn't work for you, try:
$order->getBillingAddress()->getName();
$custname = $Order->getCustomer()->getName();

PHP variable scope confused

Hello
Here is my code.... THe problem is at $product variable.
Is there any way to fix this?
It is defined two times and causes problem overwrites
THE PROBLEM UPDATED
$productsIDs = array();
foreach ($rowsProducts as &$product) {
$product["features"] = &$productsFeatures[$product["product_id"]];
$productsIDs[] = $product["product_id"];
}
//GET STOCK FEATURES
$sqlIds=implode(",",$productsIDs);
$sql="SELECT * FROM eshop_products_stock WHERE product_id IN ($sqlIds)";
$productsStock = $db->getRecordSet($sql);
$sql="SELECT * FROM `eshop_features_valuestr` WHERE feature_id IN ".
"(SELECT DISTINCT feature1_id FROM eshop_products_stock WHERE product_id IN ($sqlIds))" .
" AND language_code='$lang'";
$productsSizes = $db->getRecordSet($sql);
$sql="SELECT * FROM `eshop_features_valuestr` WHERE feature_id IN ".
"(SELECT DISTINCT feature2_id FROM eshop_products_stock WHERE product_id IN ($sqlIds))".
" AND language_code='$lang'";;
$productsColors = $db->getRecordSet($sql);
$productsSizesV=array();
foreach($productsSizes as $size)
{
$productsSizesV[$size["value"]]=$size["title"];
}
$productsColorsV=array();
foreach($productsColors as $color)
{
$productsColorsV[$color["value"]]=$color["title"];
}
//Group by product stock
$productsStockV=array();
$product="";
foreach($productsStock as $product)
{
$productsStockV[$product["product_id"]]["sizes"][]=$product["feature1_value"];
$productsStockV[$product["product_id"]]["colors"][]=$product["feature2_value"];
}
You should unset $product after the foreach loop:
foreach ($rowsProducts as &$product) {
$product["features"] = &$productsFeatures[$product["product_id"]];
$productsIDs[] = $product["product_id"];
}
unset($product);
You've encountered a very nice php WTF:
foreach ($rowsProducts as &$product) makes $product a reference. Not only for the loop but forever. If you then use a foreach using $product as the loop variable later (or do anything writing to $product), it will overwrite the last item of the first foreach loop.
Simply use foreach ($rowsProducts as $key => $product) and assign $rowsProducts[$key] = $product; at the end of your loop body if you changed anything.
Another solution would be calling unset($product); after your first loop to get rid of the reference. But generally not using reference loops is safer as you cannot forget to unset.

Categories