directory_name = $directory; $this->read(); } /** * Generates a json string representation * * @return string Json string representation */ public function to_json(): string { $retVal = [ "flights" => $this->flights, "aggregates" => $this->get_aggregates(), ]; return json_encode($retVal); } /** * Generates a json string representation of one flight * * @return string Json string representation of one flight */ public function get_flight_json($id): string { return json_encode($this->get_flight($id)); } private function get_aggregates(): array { $retVal = [ "totalFlights" => $this->total_flights, "totalPoints" => number_format(doubleval($this->total_points), 2, '.', ','), "totalDistance" => number_format(doubleval($this->total_distance), 0, '.', ','), "totalFuel" => number_format(doubleval($this->total_fuel), 1, '.', ','), ]; if (count($this->landing_rates) > 0) { $rate = 0; $lastIndex = count($this->landing_rates) - 1; if ($lastIndex % 2 == 0) { // Two elements $lowerIndex = floor($lastIndex / 2); $upperIndex = ceil($lastIndex / 2); $lowerRate = $this->landing_rates[$lowerIndex]; $upperRate = $this->landing_rates[$upperIndex]; $rate = ($lowerRate + $upperRate) / 2; } else { // One Element $lowerIndex = floor($lastIndex / 2); $lowerRate = $this->landing_rates[$lowerIndex]; $rate = $lowerRate; } $retVal["landingRate"] = number_format(doubleval($rate), 0, '.', ','); } else { $retVal["landingRate"] = "N/A"; } return $retVal; } /** * Get a specific flight * * @return array The flight */ private function get_flight(int $id): array { $flight = $this->flights[$id]; try { $rec = new \germanairlinesva\file\recording\Recording($this->directory_name . Logbook::recordings_directory . $flight["recordingFilename"] . ".rec"); $flight["recording"] = $rec->to_json(); } catch (\InvalidArgumentException) { } return $flight; } /** * Reads logbook */ private function read() { $file = fopen($this->directory_name . Logbook::file_name, "rb"); flock($file, LOCK_SH); $version = $this->read_header($file); if ($version == 1) { while ($this->read_flight_1($file) != false); } rsort($this->landing_rates); flock($file, LOCK_UN); fclose($file); } /** * Reads one flight entry * * @param resource $file File handle * * @return true If not EOF * @return false If EOF * * @throws InvalidArgumentException If file is not a resource */ private function read_flight_1($file): bool { if (false === is_resource($file)) { throw new \InvalidArgumentException(sprintf('Argument must be a valid resource type. %s given.', gettype($file))); } $retVal = []; $data = fread($file, 25); if ($data) { $retVal = array_merge($retVal, unpack(Logbook::flight_start_unpack, $data)); $size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"]; $retVal["departureAirport"] = fread($file, $size); $size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"]; $retVal["departureGate"] = fread($file, $size); $size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"]; $retVal["departureRunway"] = fread($file, $size); $size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"]; $retVal["arrivalAirport"] = fread($file, $size); $size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"]; $retVal["arrivalGate"] = fread($file, $size); $size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"]; $retVal["arrivalRunway"] = fread($file, $size); $retVal = array_merge($retVal, unpack(Logbook::flight_middle_unpack, fread($file, 65))); $size = unpack(Logbook::variable_string_size_unpack, fread($file, 1))["length"]; $retVal["recordingFilename"] = fread($file, $size); $retVal = array_merge($retVal, unpack(Logbook::flight_end_unpack, fread($file, 5))); array_push($this->flights, $retVal); $this->total_flights++; $this->total_points += $retVal["points"]; $this->total_distance += $retVal["totalDistance"]; $this->total_fuel += $retVal["totalFuel"]; array_push($this->landing_rates, $retVal["maxLandingRate"]); return true; } return false; } /** * Reads the file header * * @param resource $file File handle * * @return string File version * * @throws InvalidArgumentException If file is not a resource * @throws UnexpectedValueException If ident mismatches */ private function read_header($file): string { if (false === is_resource($file)) { throw new \InvalidArgumentException(sprintf('Argument must be a valid resource type. %s given.', gettype($file))); } $header = unpack(Logbook::header_unpack, fread($file, 5)); if ($header["ident"] !== Logbook::ident) { throw new \UnexpectedValueException(sprintf("Ident mismatch. Got %s, expected %s", $header["ident"], Logbook::ident)); } return $header["version"]; } }