/** * @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; }
/** * @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; }
/** * @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; }