1<?php 2 3use dokuwiki\Extension\SyntaxPlugin; 4use dokuwiki\HTTP\DokuHTTPClient; 5 6/** 7 * DokuWiki Plugin pegel (Syntax Component) 8 * 9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 10 * @author Andreas Gohr <dokuwiki@cosmocode.de> 11 */ 12class syntax_plugin_pegel extends SyntaxPlugin 13{ 14 public const API_URL = 'https://www.pegelonline.wsv.de/webservices/rest-api/v2'; 15 16 protected $apiResults = []; 17 18 /** @inheritDoc */ 19 public function getType() 20 { 21 return 'substition'; 22 } 23 24 /** @inheritDoc */ 25 public function getPType() 26 { 27 return 'normal'; 28 } 29 30 /** @inheritDoc */ 31 public function getSort() 32 { 33 return 155; 34 } 35 36 /** @inheritDoc */ 37 public function connectTo($mode) 38 { 39 $this->Lexer->addSpecialPattern('<pegel .*?>', $mode, 'plugin_pegel'); 40 } 41 42 /** @inheritDoc */ 43 public function handle($match, $state, $pos, Doku_Handler $handler) 44 { 45 $match = substr($match, 7, -1); 46 [$uuid, $type] = sexplode(' ', $match, 2); 47 $uuid = trim($uuid); 48 $type = trim($type); 49 if (!$type) $type = 'v'; 50 51 return [ 52 'uuid' => $uuid, 53 'type' => $type, 54 ]; 55 } 56 57 /** @inheritDoc */ 58 public function render($mode, Doku_Renderer $renderer, $data) 59 { 60 if ($mode === 'metadata') { 61 return false; 62 } 63 // for everything else we simply use cdata() 64 65 try { 66 $pegel = $this->callAPI($data['uuid']); 67 68 $station = $pegel[0]['stations'][0]; 69 $current = $station['timeseries'][0]; 70 71 switch ($data['type']) { 72 case 'v': 73 $text = $current['currentMeasurement']['value'] . $current['unit']; 74 break; 75 case 'dt': 76 $text = (new DateTime($current['currentMeasurement']['timestamp']))->format($this->getConf('dt')); 77 break; 78 case 't': 79 $text = (new DateTime($current['currentMeasurement']['timestamp']))->format($this->getConf('t')); 80 break; 81 case 'd': 82 $text = (new DateTime($current['currentMeasurement']['timestamp']))->format($this->getConf('d')); 83 break; 84 default: 85 $text = $station[$data['type']] ?? 'unknown type'; 86 } 87 } catch (Exception $e) { 88 $text = 'Error: ' . $e->getMessage(); 89 } 90 91 $renderer->cdata($text); 92 return true; 93 } 94 95 /** 96 * Fetch the data from the API 97 * 98 * @param string $uuid 99 * @return mixed 100 * @throws Exception 101 */ 102 protected function callAPI($uuid) 103 { 104 if (isset($this->apiResults[$uuid])) return $this->apiResults[$uuid]; // only one call per request 105 106 $url = self::API_URL . '/waters.json?' . http_build_query( 107 [ 108 'stations' => $uuid, 109 'includeTimeseries' => 'true', 110 'includeCurrentMeasurement' => 'true', 111 'includeStations' => 'true', 112 ], 113 '', '&' 114 ); 115 116 117 $http = new DokuHTTPClient(); 118 $ok = $http->sendRequest($url); 119 if ($ok === false) { 120 return throw new Exception('API request failed ' . $http->error, $http->status); 121 } 122 123 $data = json_decode($http->resp_body, true); 124 $this->apiResults[$uuid] = $data; 125 return $data; 126 } 127} 128