Can someone assist with this foreach loop?


#1

All I am Trying to do is Loop thru my Array fo results and out each one seperate if there is more than 1 data point:

Trying to display each of tracking # as separate line:

 getIsOrderShipped($_order->getId()); // Is oorder shipped or not

$items = $_order->getAllVisibleItems();
$trackingNumbers = [];

$trackNo = $adminHelper->getOrderTrackingNo($_order->getId());
$trackNos = explode(",", $trackNo);
if (count($trackNos)) {
    for ($i=0; $i< count($trackNos); $i++) {
        $trackingURL = $adminHelper->getTrackingUrl(strtolower($_order->getShippingDescription()), $trackNo);
        $trackingNumbers[] = array("track_no" => $trackNo, "url" => $trackingURL);
    }
}

$trackingInfoInEmail = [];
$i = 0;
if (count($trackingNumbers) > 1) {
    foreach($trackingNumbers as $trackingNumber) {
        $i++;
        $trackingInfoInEmail[] = "<a href='" . $trackingNumber[$i]['url'] . "' target='_blank'>" . $trackingNumber[$i]['track_no'] . "</a>";
        return false;
    }

}else{
        $trackingInfoInEmail[] = "<a href='" . $trackingNumbers[]['url'] . "' target='_blank'>" . $trackingNumbers[]['track_no'] . "</a>";
}
$displayShippingMethod = $adminHelper->getTrackingTextInEmail($_order->getShippingDescription()); //Shipping Method Name

if (!$isOrderShipped) {
    return false;
} else {
    if (count($items) > 0) {
        echo  "You may receive multiple shipments and emails. The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . implode(',', $trackingInfoInEmail);
    } else  {
        echo  "The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . implode(',', $trackingInfoInEmail);
    }
}

#2

So, what’s the specific problem? What was expected? What did you get? Where do you you guess which code causes the problem? Until which line your code runs fine? Where is the test data?


#3

Apparently this new code is somehow failing. I dont think I am executing correctly:

SO, It not sending out the Email, it not geting trackingnumbers my foreach loop i think is wrong


#4

Cannot use [] for reading in /Magento_Sales/templates/email/shipment/track.phtml on line 41" while reading response header from upstream, client: 10.4


#5

Is this by any chance line 41?

$trackingInfoInEmail[] = "<a href='" . $trackingNumbers[]['url'] . "' target='_blank'>" . $trackingNumbers[]['track_no'] . "</a>";

I’m wondering whether you intended to compare the trackingNumbers array count to be greater than 1, or whether you meant to check it was greater than zero. I can’t see why you would not just run the foreach() if there is 1 or more array element, and do something else if there are none.

What is in the trackingNumbers array, how many elements when you test it?


#6

You are correct:
I updated to this and now it not rendering the content:

$trackingInfoInEmail = [];
$i = 0;
if (count($trackingNumbers) > 1) {
    foreach($trackingNumbers as $trackingNumber) {
        $i++;
        $trackingInfoInEmail = "<a href='" . $trackingNumber[$i]['url'] . "' target='_blank'>" . $trackingNumber[$i]['track_no'] . "</a>";
      }

   }else{
        $trackingInfoInEmail = "<a href='" . $trackingNumber[$i]['url'] . "' target='_blank'>" . $trackingNumber[$i]['track_no'] . "</a>";
 }

#7

Looks like you’re mixing a foreach and for loop into one in way that will never work.

You should remove this complete part:

$trackingInfoInEmail = [];
$i = 0;
if (count($trackingNumbers) > 1) {
    foreach($trackingNumbers as $trackingNumber) {
        $i++;
        $trackingInfoInEmail = "<a href='" . $trackingNumber[$i]['url'] . "' target='_blank'>" . $trackingNumber[$i]['track_no'] . "</a>";
      }

   }else{
        $trackingInfoInEmail = "<a href='" . $trackingNumber[$i]['url'] . "' target='_blank'>" . $trackingNumber[$i]['track_no'] . "</a>";
 }

and replace it with

foreach ($trackingNumbers as $trackingNumber) {
    $trackingInfoInEmail[] = "<a href='" . $trackingNumber['url'] . "' target='_blank'>" . $trackingNumber['track_no'] . "</a>";
}

#8

I changed this, it works to a degree.
Now it is returning duplicated tracking numbers and each tracking number.

I need help, just get each one tracking number seperate.

    $isOrderShipped = $adminHelper->getIsOrderShipped($_order->getId()); // Is oorder shipped or not

    $items = $_order->getAllVisibleItems();
    $trackingNumbers = [];

    $trackNo = $adminHelper->getOrderTrackingNo($_order->getId());
    $trackNos = explode(",", $trackNo);
    if (count($trackNos)) {
        for ($i=0; $i< count($trackNos); $i++) {
            $trackingURL = $adminHelper->getTrackingUrl(strtolower($_order->getShippingDescription()), $trackNo);
            $trackingNumbers[] = array("track_no" => $trackNo, "url" => $trackingURL);
        }
    }

    $trackingInfoInEmail = [];
    if (count($trackingNumbers) > ) {
        for ($i=0; $i < count($trackingNumbers); $i++) {
            $trackingInfoInEmail[] = "<a href='" . $trackingNumbers[$i]['url'] . "' target='_blank'>" . $trackingNumbers[$i]['track_no'] . "</a>";
        }
    }
    $displayShippingMethod = $adminHelper->getTrackingTextInEmail($_order->getShippingDescription()); //Shipping Method Name

    if (!$isOrderShipped) {
        return false;
    } else {
        if (count($items) > 1) {
            echo  "You may receive multiple shipments and emails. The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . implode(',', $trackingInfoInEmail);
        } else  {
            echo  "The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . implode(',', $trackingInfoInEmail);
        }
    }

#9

What does that mean? Can you give an example of what you get and what you expected instead?


#10

The loop code is confusing. At the top, you create a variable called $trackNo which apparently contains a comma-separated list of tracking numbers. You then explode() it into an array called $trackNos, and then have a for() loop through it.

But, inside that loop, you create an entry in your $trackingNumbers[] array with an element called track_no which contains your initial comma-separated list. Surely in that part, you just want to put the appropriate element from $trackNos?


#11

I am struggling with this piece of code.

This is where I am with it right now and still getting duplicates.

    $isOrderShipped = $adminHelper->getIsOrderShipped($_order->getId()); // Is oorder shipped or not

    $items = $_order->getAllVisibleItems();
    $trackingNumbers = [];

    $trackNo = $adminHelper->getOrderTrackingNo($_order->getId());
    $trackNos = $adminHelper->getOrderTrackingNo($_order->getTrackingNumber());
    //$trackNos = explode(",", $trackNo);
    if (count($trackNos)) {
        for ($i=0; $i< count($trackNos); $i++) {
            $trackingURL = $adminHelper->getTrackingUrl(strtolower($_order->getShippingDescription()), $trackNo);
            $trackingNumbers[] = array("track_no" => $trackNo, "url" => $trackingURL);
        }
    }

    $trackingInfoInEmail = [];
    if (count($trackingNumbers) > 0) {
        //for ($i=0; $i < count($trackingNumbers); $i++) {
            $trackingInfoInEmail[] = "<a href='" . $trackingNumbers[$i]['url'] . "' target='_blank'>" . $trackingNumbers[$i]['track_no'] . "</a>";
        //}
    }
    $displayShippingMethod = $adminHelper->getTrackingTextInEmail($_order->getShippingDescription()); //Shipping Method Name

    if (!$isOrderShipped) {
        return false;
    } else {
    
        $i = 0;
        if (count($items) > 1) {
            echo "You may receive multiple shipments and emails.";
            foreach($items as $item) {
                $i++;
                echo "The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . implode(',', $trackingInfoInEmail);
             }
        } else {
              echo  "The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . implode(',', $trackingInfoInEmail);
        }
        
    }

#12

Same reason I gave above - you are assigning the complete list of tracking numbers that you have in $trackNo into each individual entry in your new array.

If that’s not the fault, perhaps you could respond to the question @ScallioXTX asked - what are you expecting, and what are you getting instead?


#13

I was able to Get back the Array, but when the Second email kicks-off, still returning the same tracking number from the array and not going to the next(). Can someone tell me if there is a way to if check current(), then go to next()


if (!$isOrderShipped) {
    return false;
} else {
    if (count($items) > 1 && count($trackingNumbers) >= 1) {
        echo  "You may receive multiple shipments and emails. The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . next($trackingInfoInEmail);
        next($trackingInfoInEmail);
    } else if(count($items) == 1) {
        if (count($trackingNumbers) == 1) {
            echo "The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . next($trackingInfoInEmail);
            next($trackingInfoInEmail);
        } else if (count($trackingNumbers) > 1){
            echo  "You may receive multiple shipments and emails. The tracking number for this shipment is " . $displayShippingMethod . " #&nbsp;" . next($trackingInfoInEmail);
            next($trackingInfoInEmail);
        } else if(count($trackingNumbers)==0){
            echo  "Your Order has been Shipped with" . $displayShippingMethod;
        }
    } else {
        echo  "Your Order has been Shipped with" . $displayShippingMethod;
    }
}

#14

use for loop instead of foreach loop.
for($i =0; $i<sizeof(trackingNumbers); $i++) {}