Пример #1
0
 /**
  * @inheritdoc
  */
 public function getData($value, $searchType = self::SEARCH_CONTAINER)
 {
     $jar = new CookieJar();
     $searches = [self::SEARCH_CONTAINER => 'CONTAINERNUMBER', self::SEARCH_BOL => 'BLNUMBER'];
     //we need receive cookies first
     $response = $this->getClient()->request('POST', $this->serviceUrl, ['form_params' => ['portlet_trackSimple_1wlw-select_key:{pageFlow.trackSimpleForm.type}' => $searches[$searchType], 'portlet_trackSimple_1{pageFlow.trackSimpleForm.numbers}' => $value, 'portlet_trackSimple_1wlw-select_key:{pageFlow.trackSimpleForm.type}OldValue' => true], 'cookies' => $jar, 'headers' => ['Referer' => "http://classic.maerskline.com/appmanager/maerskline/public?_nfpb=true&_nfls=false&_pageLabel=page_tracking3_trackSimple"]]);
     if ($response->getStatusCode() != 200) {
         throw new \Exception("Service GET url ={$this->serviceUrl} unavailable");
     }
     $html = (string) $response->getBody();
     $dom = new \DOMDocument();
     libxml_use_internal_errors(true);
     $dom->preserveWhiteSpace = false;
     $dom->loadHTML($html);
     $this->xpath = new \DOMXPath($dom);
     $table = $this->xpath->query('//table[@class = "lstBox"]');
     if (!$table->length) {
         throw new \Exception("Data not found for container {$value}");
     }
     $href = $this->xpath->query('./tr[2]/td[4]/a/@href', $table->item(0));
     $urlEvents = $this->getDomNodeValue($href);
     if (!$urlEvents) {
         throw new \Exception("Incorrect format for container {$value}");
     }
     $result = new DataResult();
     $item = $this->xpath->query('./tr[2]/td[8]', $table->item(0));
     $result->setLastPort($this->getDomNodeValue($item));
     $item = $this->xpath->query('./tr[2]/td[9]', $table->item(0));
     $eta = $this->getDomNodeValue($item);
     if (!$eta) {
         throw new \Exception("Incorrect format for container {$value}: ETA not found");
     }
     $result->setEta((new \DateTime($eta))->format('Y-m-d'));
     //we need receive cookies first
     $response = $this->getClient()->request('GET', $urlEvents, ['cookies' => $jar]);
     if ($response->getStatusCode() != 200) {
         throw new \Exception("Service GET url ={$this->serviceUrl} unavailable");
     }
     $html = (string) $response->getBody();
     $dom = new \DOMDocument();
     libxml_use_internal_errors(true);
     $dom->preserveWhiteSpace = false;
     $dom->loadHTML($html);
     $this->xpath = new \DOMXPath($dom);
     $eventTableHeaders = $this->xpath->query('//table[tr/td = "Location"]');
     if ($eventTableHeaders->length == 0) {
         throw new \Exception("Event table not found for {$value}");
     }
     $headers = $this->xpath->query('./tr[2]/td', $eventTableHeaders->item(0));
     $out = ['Activity', 'Location', 'Date, Time', 'Vessel/Carrier', 'Voyage'];
     foreach ($headers as $header) {
         $expected = array_shift($out);
         if ($expected != trim($header->nodeValue)) {
             throw new \Exception("Table format error, expected {$expected} got {$header->nodeValue} for {$value}");
         }
     }
     $eventsTable = $this->xpath->query('./tr[position() > 2]', $eventTableHeaders->item(0));
     $wasNowEvent = false;
     foreach ($eventsTable as $row) {
         $event = new EventResult();
         $isNowEvent = $this->xpath->query('./td[contains(@class, "lstNow")]', $row)->length;
         $event->setStatus($this->getDomNodeValue($this->xpath->query('./td[1]//span', $row)));
         $event->setLocation($this->getDomNodeValue($this->xpath->query('./td[2]//span', $row)));
         $date = $this->getDomNodeValue($this->xpath->query('./td[3]//span', $row));
         $event->setDate((new \DateTime($date))->format('Y-m-d H:i'));
         $event->setVessel($this->getDomNodeValue($this->xpath->query('./td[4]//span', $row)));
         $event->setVoyage($this->getDomNodeValue($this->xpath->query('./td[5]//span', $row)));
         if ($isNowEvent) {
             $wasNowEvent = true;
         }
         if ($wasNowEvent && !$isNowEvent) {
             $result->addFutureEvent($event);
         } else {
             $result->addEvent($event);
         }
     }
     foreach ($result->getEvents() as $event) {
         if ($event->getLocation() == $result->getLastPort() && $event->getStatus() == 'Discharge Full') {
             $result->setAta($event->getDate());
         }
         //First Load = LoadOnVesselAt
         if (!$result->getLoadOnVesselAt() && $event->getStatus() == 'Load Full') {
             $result->setPol($event->getLocation());
             $result->setLoadOnVesselAt($event->getDate());
         }
     }
     $containerDetails = $this->xpath->query('//fieldset[legend = "Container details"]/table/tr[2]')->item(0);
     $size = $this->getDomNodeValue($this->xpath->query('./td[2]', $containerDetails));
     $type = $this->getDomNodeValue($this->xpath->query('./td[3]', $containerDetails));
     $result->setContainerSize($size);
     $result->setContainerType($type);
     $mbl = $this->getDomNodeValue($this->xpath->query('//fieldset[legend = "Document details"]/table/tr[2]/td[1]'));
     $result->setBillOfLanding($mbl);
     return $result;
 }
Пример #2
0
 /**
  * @inheritdoc
  */
 public function getData($value, $searchType = self::SEARCH_CONTAINER)
 {
     $searches = [self::SEARCH_CONTAINER => '2', self::SEARCH_BOL => '1'];
     if ($searchType == self::SEARCH_CONTAINER) {
         $this->serviceUrl .= '&numbers=&numbers=&numbers=&numbers=&numbers=&numbers=&numbers=&numbers=&numbers=';
     } else {
         if ($searchType == self::SEARCH_BOL) {
             $value = str_replace('HDMU', '', $value);
         }
     }
     $response = $this->getClient()->request('POST', $this->serviceUrl . $value, ['form_params' => ['type' => $searches[$searchType], 'number' => $value, 'numbers' => $value, 'blFields' => 1, 'cnFields' => 1, 'is_quick' => 'Y'], 'headers' => ['Origin' => 'http://hmm21.com', 'Referer' => 'http://hmm21.com']]);
     if ($response->getStatusCode() != 200) {
         throw new \Exception("Service GET url ={$this->serviceUrl} unavailable");
     }
     $html = (string) $response->getBody();
     $dom = new \DOMDocument();
     libxml_use_internal_errors(true);
     $dom->preserveWhiteSpace = false;
     $dom->loadHTML($html);
     $this->xpath = new \DOMXPath($dom);
     // Main table
     $mainTable = $this->xpath->query('.//*[@id=\'viewForm\']/div[@class="progressChart"]/table[contains(@class, "business02")]/tbody');
     if ($mainTable->length == 0) {
         return null;
     }
     $result = new DataResult();
     $tableHeader = $this->xpath->query('.//*[@id=\'viewForm\']/div[@class="progressChart"]/table[contains(@class, "business02")]/thead/tr/th/font');
     $origin = trim($tableHeader->item(0)->nodeValue);
     $destination = trim($tableHeader->item($tableHeader->length - 1)->nodeValue);
     if ($origin != 'Origin' || $destination != 'Destination') {
         throw new \Exception("Incorrect table layout for Main information");
     }
     $item = $this->xpath->query('./tr[1]/td[1]', $mainTable->item(0));
     $pol = $this->getDomNodeValue($item);
     $result->setPol($pol);
     $item = $this->xpath->query('./tr[1]/td[last()]', $mainTable->item(0));
     $pod = $this->getDomNodeValue($item);
     $result->setLastPort($pod);
     $itemEta = $this->xpath->query('./tr[2]/td[last()]/font[@color="red"]', $mainTable->item(0));
     if ($itemEta->length) {
         $eta = preg_replace('/[^a-zA-Z\\-\\d]+/', '', $itemEta->item(0)->nodeValue) . ' ' . preg_replace('/[^:\\d]+/', '', $itemEta->item(1)->nodeValue);
         $eta = new \DateTime($eta);
         if ($eta) {
             $result->setEta($eta->format('Y-m-d H:i'));
         }
     }
     $itemAta = $this->xpath->query('./tr[2]/td[last()]/font[@color="blue"]', $mainTable->item(0));
     if ($itemAta->length) {
         $ata = preg_replace('/[^a-zA-Z\\-\\d]+/', '', $itemAta->item(0)->nodeValue) . ' ' . preg_replace('/[^:\\d]+/', '', $itemAta->item(1)->nodeValue);
         $ata = new \DateTime($ata);
         if ($ata) {
             $result->setAta($ata->format('Y-m-d H:i'));
         }
     }
     // Container info
     $tableHeader = $this->getTableHeader($this->xpath->query('.//*[@id=\'trackingForm\']/table[contains(@class, "business02")][1]/thead/tr/th'));
     if ($tableHeader == self::$tableHeaders['container']) {
         $item = $this->xpath->query('.//*[@id=\'trackingForm\']/table[contains(@class, "business02")][1]/tbody/tr/td[2]');
         $containerType = $this->getDomNodeValue($item);
         $containerData = explode('/', $containerType);
         if (count($containerData) == 2) {
             $result->setContainerType($containerData[0]);
             $result->setContainerSize($containerData[1]);
         } else {
             $result->setContainerType($containerData[0]);
         }
     } else {
         throw new \Exception("Incorrect table layout for Container information");
     }
     //  Shipment Progress table
     $tableHeader = $this->getTableHeader($this->xpath->query('.//*[@id=\'trackingForm\']/table[contains(@class, "business02")][3]/thead/tr/th'));
     if ($tableHeader == self::$tableHeaders['shipment_progress']) {
         $eventRows = $this->xpath->query('.//*[@id=\'trackingForm\']/table[contains(@class, "business02")][3]/tbody/tr');
         foreach ($eventRows as $row) {
             $event = new EventResult();
             $item = $this->xpath->query("td[1]", $row);
             $date = $this->getDomNodeValue($item);
             $item = $this->xpath->query("td[2]", $row);
             $time = preg_replace('/[^:\\d]+/', '', $this->getDomNodeValue($item));
             $datetime = $date . ' ' . $time;
             $event->setDate((new \DateTime($datetime))->format('Y-m-d H:i'));
             $item = $this->xpath->query("td[3]", $row);
             $location = $this->getDomNodeValue($item);
             $event->setLocation($location);
             $item = $this->xpath->query("td[4]", $row);
             $status = $this->getDomNodeValue($item);
             $event->setStatus($status);
             $item = $this->xpath->query("td[5]", $row);
             $vessel = $this->getDomNodeValue($item);
             $event->setVessel($vessel);
             $result->addEvent($event);
         }
     } else {
         throw new \Exception("Incorrect table layout for Shipment Progress");
     }
     foreach ($result->getEvents() as $event) {
         //First Load = LoadOnVesselAt
         if (preg_match('/Shipped on/', $event->getStatus())) {
             $result->setLoadOnVesselAt($event->getDate());
         }
     }
     return $result;
 }
Пример #3
0
 /**
  * @inheritdoc
  */
 public function getData($value, $searchType = self::SEARCH_CONTAINER)
 {
     $jar = new CookieJar();
     //we need receive cookies first
     $response = $this->getClient()->request('GET', $this->serviceUrl . $value, ['cookies' => $jar]);
     if ($response->getStatusCode() != 200) {
         throw new \Exception("Service GET url ={$this->serviceUrl} unavailable");
     }
     //with cookies we can get info
     $response = $this->getClient()->request('GET', $this->serviceUrlFrame, ['cookies' => $jar, 'headers' => ['Referer' => $this->serviceUrl . $value]]);
     if ($response->getStatusCode() != 200) {
         throw new \Exception("Service GET url ={$this->serviceUrlFrame} unavailable");
     }
     $html = (string) $response->getBody();
     $dom = new \DOMDocument();
     libxml_use_internal_errors(true);
     $dom->preserveWhiteSpace = false;
     $dom->loadHTML($html);
     $this->xpath = new \DOMXPath($dom);
     $checkNotFound = $this->xpath->query('//strong[text() = "Not Found:"]');
     if ($checkNotFound->length == 1) {
         throw new \Exception("Data not found for container {$value}");
     }
     $eventRows = $this->xpath->query('//h3[contains(text(), "Routing")]/following::table[1]/tbody/tr[position() > 1]');
     if ($eventRows->length == 0) {
         throw new \Exception("Cant find event tables for container {$value}!");
     }
     $result = new DataResult();
     foreach ($eventRows as $row) {
         $event = new EventResult();
         $item = $this->xpath->query("td[1]", $row);
         $route = $this->getDomNodeValue($item);
         $route = preg_replace('/[^a-zA-Z\\d ]/', '', $route);
         $item = $this->xpath->query("td[2]/a", $row);
         $location = $this->getDomNodeValue($item);
         $event->setLocation($location);
         if ($route == 'Origin') {
             $result->setPol($location);
         }
         if ($route == 'Destination') {
             $result->setLastPort($location);
         }
         $item = $this->xpath->query("td[3]/a", $row);
         $vessel = $this->getDomNodeValue($item);
         $event->setVessel($vessel);
         $item = $this->xpath->query("td[4]", $row);
         $arrivalDateStr = $this->getDomNodeValue($item);
         $arrivalDateStr = preg_replace('/([^a-zA-Z\\d ]+)/', ' ', $arrivalDateStr);
         if ($arrivalDateStr) {
             preg_match('/(?<date>\\d{1,2} \\w{3} \\d{2}) (?<type>\\w{1})/', $arrivalDateStr, $matches);
             if (isset($matches['date'])) {
                 $date = (new \DateTime($matches['date']))->format('Y-m-d');
                 $event->setDate($date);
                 $status = $route . ' arrival';
                 $event->setStatus($status);
                 $type = $matches['type'];
                 if ($route == 'Destination' && $type == 'A') {
                     $result->setAta($date);
                 }
                 if (in_array($type, ['E', 'P'])) {
                     if ($route == 'Destination') {
                         $result->setEta($date);
                     }
                     $result->addFutureEvent($event);
                 } else {
                     $result->addEvent($event);
                 }
             }
         }
         $item = $this->xpath->query("td[5]", $row);
         $departureDateStr = $this->getDomNodeValue($item);
         $departureDateStr = preg_replace('/([^a-zA-Z\\d ]+)/', ' ', $departureDateStr);
         if ($departureDateStr) {
             $matches = [];
             preg_match('/(?<date>\\d{1,2} \\w{3} \\d{2}) (?<type>\\w{1})/', $departureDateStr, $matches);
             if (isset($matches['date'])) {
                 $event = clone $event;
                 $type = $matches['type'];
                 $date = new \DateTime($matches['date']);
                 $event->setDate($date->format('Y-m-d'));
                 if ($route == 'Load Port' && $type == 'L') {
                     $result->setLoadOnVesselAt($date->format('Y-m-d'));
                 }
                 $status = $route . ' departure';
                 $event->setStatus($status);
                 if (in_array($type, ['E', 'P'])) {
                     $result->addFutureEvent($event);
                 } else {
                     $result->addEvent($event);
                 }
             }
         }
     }
     $containerData = $this->xpath->query('//h3[contains(text(), "Containers")]/following::table[1]/tbody/tr[2]');
     $item = $this->xpath->query('./td[2]', $containerData->item(0));
     $type = $this->getDomNodeValue($item);
     $result->setContainerType($type);
     $item = $this->xpath->query('./td[3]', $containerData->item(0));
     $size = $this->getDomNodeValue($item);
     $result->setContainerSize($size);
     return $result;
 }