I’m trying to get estimated delivery dates for various products but rather than working it out for each product it adds the previous delivery time onto the next product before working it out.
This is what I’ve got so far
public function getDeliveryDate() {
$ndd = $this->getPhysicalOrderProducts();
$arrive = $this->getPostDate();
$arrive->add(new DateInterval('P'.$ndd[0]->getDeliveryTime().'D'));
return $arrive;
}
I want it get a product, add the DeliveryTime to PostDate then return that as $date I then want it to go on to the next product and do the same thing. At the moment what’s happening is it’s getting the date, adding the delivery time. Then with the next date it’s adding the previous delivery time to the result of $date from the previous product.
Is there anyway to get it to recalculate it from fresh for every product?
The problem is that objects are passed by reference, so when you do $arrive = $this->getPostDate(); then the variable $arrive is now pointing to the same DateTime object that is being used for the post date elsewhere in your object.
What you want to do is clone the original object, so that when you add the delivery time to the clone it doesn’t affect the original:
$arrive = clone $this->getPostDate();
It might be a good idea to do the cloning within the getPostDate() method instead, as this will prevent the original post date from being modified by accident by other code.
(Note that if you’re using PHP 5.5, you can use the DateTimeImmutable class)
Thank you for your help I tried to use clone and it worked better, it showed both dates as the same which is an improvement. What I want though is if I add 3 days to first product and 1 to the next it should add that to the original date. When I added clone it added 3 days to the original date for both products.
Also I’m running PHP version 5.4.24 if that helps.
This seems a little odd, as you’re iterating over products but not actually doing anything with each item. You’re calling entry.getDeliveryDate() each time, but surely the return value will be the same each time, as it’s the same object?
Not always but often an order will have multiple products in it each with different delivery time. When somebody places an order I want the receipt to show the order along with the expected delivery date for each product. This is how I’m trying to do it.
Unfortunately because different products ship from different places the delivery time will be different for each product.
{% for op in products %}
<li>{{ entry.getDeliveryDate|date("d/m/Y") }}</li>
{% endfor %}
you’re looping all the products in your order, and for each iteration of the loop op is the current product. So shouldn’t it be calling op.getDeliveryDate? Currently, if there are 5 products in products then the loop will obviously run 5 times, but each time entry is still the same object. Or have I misunderstood how your code works?
What normally happens is when somebody places an order the results go though various functions to do things like push the order to Zendesk, to database etc.
The code that sets the values should be these though:
public function getDeliveryDate() {
$ops = $this->getPhysicalOrderProducts();
$date = clone $this->getPostDate();
$date->add(new \\DateInterval('P'.$ops[0]->getDeliveryTime().'M'));
return $date;
}
and
public function getPhysicalOrderProducts()
{
$products = array();
foreach($this->getOrderProducts() as $op) {
if($op->getProduct()->isPostable()) {
$products[] = $op;
}
}
return $products;
}
Although the actual file (a pdf which is generated from the page where the results are is this:
public function generateReceipt($app)
{
$products = $this->getPhysicalOrderProducts();
if (count($products) > 0) {
$filename = $this->getOrderReceiptFilename($app);
if (!file_exists($filename)) {
// Generate HTML
$html = $app['twig']->render('order/receipt.twig', array(
'entry' => $this,
'products' => $products,
'content_height' => intval( (8*100*count($products))/95 )+1,
'domain' => $app['config']['domain'],
));
// Generate PDF
$snappy = new Pdf($app['wkhtmltox_bin']);
$snappy->setOption('orientation', 'landscape');
$snappy->generateFromHtml(utf8_decode($html), $filename);
}
}
}
If it would be more helpful I could send you the files? Unfortunately it’s an intranet site so I can’t give you access to it