/** * TemplateResult constructor. * @param array $template * @param array $data */ public function __construct($template, array $data) { $this->template = $template; parent::__construct($data); }
/** * @inheritdoc */ public function getData($value, $searchType = self::SEARCH_CONTAINER) { $searches = [self::SEARCH_CONTAINER => 'ct', self::SEARCH_BOL => 'bl']; $response = $this->getClient()->request('POST', $this->serviceUrl, ['form_params' => ['searchby' => $searches[$searchType], 'Submit' => 'Search', 'number1' => $value]]); 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->loadHTML($html); $this->xpath = new \DOMXPath($dom); $notFound = $this->xpath->query("//td[text()='Unit is not belong to FESCO or number is incorrect']"); if ($notFound->length) { throw new \Exception("No data for {$value}"); } $result = new DataResult(); // result $event = new EventResult(); $item = $this->xpath->query('//tr[last()]/td[2]/text()[1]'); $status = $this->getDomNodeValue($item); $result->setCurrentStatus($status); $event->setStatus($status); $item = $this->xpath->query('//tr[last()]/td[2]/text()[2]'); $containerType = $this->getDomNodeValue($item); $result->setContainerType($containerType); $item = $this->xpath->query('//tr[last()]/td[3]/text()[1]'); $date = preg_replace('/[^a-zA-Z\\-\\d]+/', ' ', $this->getDomNodeValue($item)); //some strange chars in date $item = $this->xpath->query('//tr[last()]/td[3]/span/span/text()'); $location = $this->getDomNodeValue($item); $event->setLocation($location); if ($date) { $date = \DateTime::createFromFormat("d M Y", $date)->format('Y-m-d'); $event->setDate($date); if ($status == 'Loaded with cargo on vessel') { $result->setLoadOnVesselAt($date); } if ($status == 'Discharged with cargo from vessel') { $result->setAta($date); $result->setLastPort($location); } } $item = $this->xpath->query('//tr[last()]/td[4]/text()[1]'); $eta = strtr($this->getDomNodeValue($item), [chr(160) => ' ', chr(194) => '']); if ($eta) { $result->setEta((new \DateTime($eta))->format('Y-m-d')); } $item = $this->xpath->query('//tr[last()]/td[4]/text()[2]'); $ports = $this->getDomNodeValue($item); if ($ports) { $ports = explode('-', $ports); $result->setPol(trim($ports[0])); if (isset($ports[1]) && !$result->getLastPort()) { $result->setLastPort(trim($ports[1])); } } $item = $this->xpath->query('//tr[last()]/td[5]/text()'); $vesselVoyage = $this->getDomNodeValue($item); if ($vesselVoyage) { $vesselVoyage = explode('/', $vesselVoyage); $event->setVessel(trim($vesselVoyage[0])); if (isset($vesselVoyage[1])) { $event->setVoyage(trim($vesselVoyage[1])); } } $result->addEvent($event); return $result; }
/** * @inheritdoc */ public function getData($value, $searchType = self::SEARCH_CONTAINER) { $response = $this->getClient()->request('GET', $this->serviceUrl, ['query' => ['searchNumber' => $value]]); if ($response->getStatusCode() != 200) { throw new \Exception("Service unavailable or there is no data for container {$value}"); } $html = (string) $response->getBody(); $result = new DataResult(); // result $dom = new \DOMDocument(); libxml_use_internal_errors(true); $dom->loadHTML($html); $this->xpath = new \DOMXPath($dom); $item = $this->xpath->query('//h4[contains(text(), "Bill of lading No.")]/a'); $billOfLanding = $this->getDomNodeValue($item); if (!$billOfLanding) { throw new \Exception("Format error {$value}: Bill of landing No was not found"); } $item = $this->xpath->query('//tr[@class="container-row"]/td/span[@class="muted"]'); $containerType = $this->getDomNodeValue($item); if (!$containerType) { throw new \Exception("Format error {$value}: Container type was not found"); } $item = $this->xpath->query('//span[@class="ETA-block"]/text()[2]'); $eta = $this->getDomNodeValue($item); if (!$eta) { throw new \Exception("Format error {$value}: ETA was not found"); } $eta = (new \DateTime($eta))->format('Y-m-d H:i'); $result->setBillOfLanding($billOfLanding); $result->setEta($eta); $result->setContainerType($containerType); //получаем все таблицы с датами $list = $this->xpath->query("//table[contains(@class, 'container-move')]"); if ($list->length == 0) { //events info url $item = $this->xpath->query("//a[@data-url]/attribute::data-url"); $detailsUrl = $this->getDomNodeValue($item); if (!$detailsUrl) { throw new \Exception("Format error {$value}: url for events info was not found"); } $detailsUrl = "http://my.maerskline.com/{$detailsUrl}"; $response = $this->getClient()->get($detailsUrl); if ($response->getStatusCode() != 200) { throw new \Exception("Cant find event tables for container {$value}!"); } $html = (string) $response->getBody(); $dom = new \DOMDocument(); $dom->preserveWhiteSpace = false; libxml_use_internal_errors(true); $dom->loadHTML($html); $this->xpath = new \DOMXPath($dom); $list = $this->xpath->query("//table[contains(@class, 'container-move')]"); if ($list->length == 0) { throw new \Exception("Cant find event tables for container {$value}!"); } } $i = 0; foreach ($list as $item) { $class = $item->attributes->getNamedItem('class')->nodeValue; $event = new EventResult(); $locItem = $this->xpath->query("preceding-sibling::h4[1]", $item); // это Location события $location = $this->getDomNodeValue($locItem); $event->setLocation($location); $itemDate = $this->xpath->query(".//td[3]/text()", $item); $date = ''; foreach ($itemDate as $datePart) { if ($date) { $date .= ' '; } $date .= trim($datePart->nodeValue); } $event->setDate((new \DateTime($date))->format('Y-m-d H:i')); $statusTD = $this->xpath->query(".//td[4]", $item)->item(0); $statusItem = $this->xpath->query("strong", $statusTD); $status = $this->getDomNodeValue($statusItem); $event->setStatus($status); $voyageItem = $this->xpath->query("small", $statusTD); $voyage = $this->getDomNodeValue($voyageItem); $event->setVoyage($voyage ? str_replace('Voyage: ', '', $voyage) : $voyage); $vesselItem = $this->xpath->query("text()", $statusTD); $vessel = null; if ($vesselItem->length) { for ($j = 0; $j < $vesselItem->length; $j++) { $value = trim($vesselItem->item($j)->nodeValue); if ($value) { $vessel = $value; } } } $event->setVessel($vessel); $eventKey = strpos($class, 'future') === false ? 'Events' : 'FutureEvents'; if ($eventKey == 'Events') { $result->addEvent($event); } else { $result->addFutureEvent($event); } $i++; } foreach ($result->getEvents() as $event) { //First Load = LoadOnVesselAt if (!$result->getLoadOnVesselAt() && preg_match('/Load/', $event->getStatus())) { $result->setLoadOnVesselAt($event->getDate()); } //Last discharge = ATA if (!$result->getFutureEvents() && preg_match('/discharge/i', $event->getStatus())) { $result->setAta($event->getDate()); } } return $result; }