/** * Decode a full taf string into a complete taf object * @param $raw_taf * @param $strict * @return DecodedTaf */ private function parseWithMode($raw_taf, $strict) { // prepare decoding inputs/outputs: (trim, remove linefeeds and returns, no more than one space) $clean_taf = trim($raw_taf); $clean_taf = preg_replace("#\n+#", ' ', $clean_taf); $clean_taf = preg_replace("#\r+#", ' ', $clean_taf); $clean_taf = preg_replace('#[ ]{2,}#', ' ', $clean_taf) . ' '; $clean_taf = strtoupper($clean_taf); if (strpos($clean_taf, 'CNL') === false) { // appending END to it is necessary to detect the last line of evolution // but only when the TAF wasn't cancelled (CNL) $remaining_taf = trim($clean_taf) . ' END'; } else { $remaining_taf = $clean_taf; } $decoded_taf = new DecodedTaf($clean_taf); $with_cavok = false; // call each decoder in the chain and use results to populate decoded taf foreach ($this->decoder_chain as $chunk_decoder) { try { // try to parse a chunk with current chunk decoder $decoded = $chunk_decoder->parse($remaining_taf, $with_cavok); // map obtained fields (if any) to the final decoded object $result = $decoded['result']; if ($result != null) { foreach ($result as $key => $value) { if ($value !== null) { $setter_name = 'set' . ucfirst($key); $decoded_taf->{$setter_name}($value); } } } // update remaining taf for next round $remaining_taf = $decoded['remaining_taf']; } catch (ChunkDecoderException $cde) { // log error in decoded taf and abort decoding if in strict mode $decoded_taf->addDecodingException($cde); // abort decoding if strict mode is activated, continue otherwise if ($strict) { break; } // update remaining taf for next round $remaining_taf = $cde->getRemainingTaf(); } // hook for CAVOK decoder, keep CAVOK information in memory if ($chunk_decoder instanceof VisibilityChunkDecoder) { $with_cavok = $decoded_taf->getCavok(); } } // weather evolutions $evolutionDecoder = new EvolutionChunkDecoder($strict, $with_cavok); while ($remaining_taf != null && trim($remaining_taf) != 'END') { $evolutionDecoder->parse($remaining_taf, $decoded_taf); $remaining_taf = $evolutionDecoder->getRemaining(); } return $decoded_taf; }
/** * Add the evolution to the decodedTaf's entity * * @param DecodedTaf $decoded_taf * @param Evolution $evolution * @param array $result * @param string $entity_name */ private function addEvolution($decoded_taf, $evolution, $result, $entity_name) { // clone the evolution entity /** @var Evolution $newEvolution */ $new_evolution = clone $evolution; // add the new entity to it $new_evolution->setEntity($result[$entity_name]); // possibly add cavok to it if ($entity_name == 'visibility' && $this->with_cavok == true) { $new_evolution->setCavok(true); } // get the original entity from the decoded taf or a new one decoded taf doesn't contain it yet $getter_name = 'get' . ucfirst($entity_name); $setter_name = 'set' . ucfirst($entity_name); $decoded_entity = $decoded_taf->{$getter_name}(); if ($decoded_entity == null || $entity_name == 'clouds') { // that entity is not in the decoded_taf yet, or it's a cloud layer which is a special case $decoded_entity = $this->instantiateEntity($entity_name); } // add the new evolution to that entity $decoded_entity->addEvolution($new_evolution); // update the decoded taf's entity or add the new one to it if ($entity_name == 'clouds') { $decoded_taf->addCloud($decoded_entity); } else { $decoded_taf->{$setter_name}($decoded_entity); } }