public function Track($trackingNumber)
 {
     if (preg_match("/^[A-Z0-9]{13}\$/", $trackingNumber) === 0) {
         throw new RoyalMailException("Not a valid tracking number - does not match required format");
     }
     $doc = new DOMDocument();
     $doc->preserveWhiteSpace = FALSE;
     $doc->loadHTMLFile("https://www.royalmail.com/track-your-item?trackNumber=" . $trackingNumber);
     $divs = $doc->getElementsByTagName('table');
     @($children = $divs->item(0)->childNodes->item(1));
     // Targeting first <Table> on page and then second child of that table, i.e. <Tbody>
     @($trackingStatus = $children->childNodes);
     // child nodes of the <Tbody>, i.e. the <tr>'s containing table cells for tracking data.
     $statusArray = array();
     // Try to get the product name, e.g. Special Delivery or Recorded.
     // There's something really funky going on with the white space here so I'm calling a static function removeEmptyNodes() to strip empty DOMText children.
     $service1 = $doc->getElementById((string) $trackingNumber);
     // Targeting element with ID of the tracking number.
     $service2 = RoyalMail::removeEmptyNodes($service1);
     // Strip empty DOMText children from service1 and save into service2.
     if ($service2->childNodes->length > 1) {
         $service3 = RoyalMail::removeEmptyNodes($service2->childNodes->item(0));
         // Currently in ".rml-track-trace-result" and descend into first child (".result-column colour-white")
     }
     if ($service3->childNodes->length > 1) {
         $service4 = RoyalMail::removeEmptyNodes($service3->childNodes->item(1));
         // Currently in ".result-column colour-white", descend into second child ("p")
         $serviceType = $service4->childNodes->item(0)->textContent;
         // Currently in "p", descend into first child (".product strong") and get node value and save it.
     }
     foreach ($trackingStatus as $statusLine) {
         // Each <Tr> is a status update, loop through the <Tr>'s and extract data from the <Td>'s contained within for our output array.
         $outStatusLine = array();
         $outStatusLine['date'] = $statusLine->childNodes->item(0)->textContent;
         $outStatusLine['time'] = $statusLine->childNodes->item(1)->textContent;
         $outStatusLine['report'] = $statusLine->childNodes->item(2)->textContent;
         $outStatusLine['location'] = $statusLine->childNodes->item(3)->textContent;
         $statusArray[] = $outStatusLine;
     }
     // Do a bit of basic error handling, needs improvement.
     // If the tracking number is not found then the DOM parsing will be targeting a different table on the page and we will just test for that.
     if (!is_numeric(substr($statusArray[0]['date'], 0, 1))) {
         throw new RoyalMailException('Unexpected output - may not be a valid tracking number');
     }
     // Now we have the status updates, before we return them, let's make a decision on whether it's been delivered or not:
     if (substr($statusArray[0]['report'], 0, 9) == "DELIVERED") {
         $delivered = "True";
     } else {
         $delivered = "False";
     }
     // Now return the output, item 0 in the return array is our delivery decision and item 1 is an array of status updates:
     return array('rmService' => $serviceType, 'deliveryDecision' => $delivered, 'statusLines' => $statusArray);
 }
Example #2
0
 public function getRoyalMailRates($id_zone, $is_cart, $cart, $product_weight, $dest_zip, $dest_state, $dest_country, $currency, $product, $id_product_attribute, $qty, $dest_city)
 {
     $rates = array();
     if (file_exists(dirname(__FILE__) . '/../../royalmail/classes/RateAvailableServices.php')) {
         include_once dirname(__FILE__) . '/../../royalmail/royalmail.php';
         include_once dirname(__FILE__) . '/../../royalmail/classes/RateAvailableServices.php';
         $rm = new RoyalMail();
         if ($rm->active) {
             $handling = Configuration::get('PS_SHIPPING_HANDLING');
             $carriers = $rm->getCarriers($id_zone, $cart, $is_cart, $product);
             foreach ($carriers as $carrier) {
                 if (get_parent_class($rm) == 'PrestoChangeoCarrierModule') {
                     $rm_rate = new RoyalMailRate();
                     $amount = $rm_rate->getRate($carrier['id_carrier'], $carrier['id_zone'], $is_cart != '' ? $cart->getTotalWeight() : max($product_weight, 0.001), $dest_zip, $dest_state, $dest_country, "", $is_cart != '' ? 0 : $product->getPrice(true, $id_product_attribute, 6, NULL, false, true, $qty), $is_cart != '' ? 0 : $product->id, $is_cart != '' ? 0 : $id_product_attribute, $qty);
                 } else {
                     $amount = getRoyalMailRate($carrier['id_carrier'], $carrier['id_zone'], $is_cart != '' ? $cart->getTotalWeight() : max($product_weight, 0.001), $dest_zip, $dest_country, $is_cart != '' ? 0 : $product->getPrice(true, $id_product_attribute, 6, NULL, false, true, $qty), $is_cart != '' ? 0 : $product->id);
                 }
                 // Add product spercific cost + handling fee
                 if ($amount > 0) {
                     $amount += $this->getExtraShippingCost($carrier, $handling, $is_cart != '' ? $cart->getProducts() : array(), $product, $qty);
                 }
                 // Apply shipping tax if needed
                 if (!Tax::excludeTaxeOption()) {
                     $carrierTax = Tax::getCarrierTaxRate($carrier['id_carrier']);
                 }
                 if (isset($carrierTax) && $amount !== false) {
                     $amount *= 1 + $carrierTax / 100;
                 }
                 $amount = $amount === false ? -1 : Tools::convertPrice($amount, $currency);
                 if ($amount > 0) {
                     $rates[$carrier['name']] = array(Tools::displayPrice($amount, $currency, false), $carrier['id_carrier']);
                 } elseif ($amount !== false && $amount == 0) {
                     $rates[$carrier['name']] = array($ap->l('Free!'), $carrier['id_carrier']);
                 }
             }
         }
     }
     return $rates;
 }
#!/usr/bin/php
<?php 
require_once "RoyalMailTracker.php";
if ($_SERVER['argc'] != 2) {
    echo "Usage: RoyalMailTrack.php TRACKING_NUMBER";
    echo "\n";
    exit(1);
}
try {
    $rm = new RoyalMail();
    $tracker = $rm->Track($_SERVER['argv'][1]);
    // First print the service type
    echo "Service: " . $tracker['rmService'] . "\n\n";
    // First print the delivery decision:
    if ($tracker['deliveryDecision'] == "True") {
        echo "This item has been delivered.";
    } else {
        echo "This item has not been delivered.";
    }
    echo "\n\n";
    // Then print the status updates:
    echo "** Status updates for this item **\n\n";
    foreach ($tracker['statusLines'] as $statusUpdate) {
        echo $statusUpdate['date'] . " " . $statusUpdate['time'] . " - " . $statusUpdate['report'] . " - " . $statusUpdate['location'];
        echo "\n";
    }
} catch (Exception $e) {
    echo $e->getMessage();
}
echo "\n";
Example #4
0
<?php

require_once "RoyalMailTracker.php";
try {
    $rm = new RoyalMail();
    $tracker = $rm->Track($_GET['t']);
    echo json_encode($tracker);
} catch (Exception $e) {
    $err = array('error' => $e->getMessage());
    echo json_encode($err);
}
echo "\n";