1<?php 2 3include_once(dirname(__FILE__) . join(DIRECTORY_SEPARATOR, array('idoit', 'php', 'apiclient.php'))); 4 5use idoit\Api\Client as ApiClient; 6use idoit\Api\Request as Request; 7use idoit\Api\CMDB\Object as CMDBObject; 8use idoit\Api\CMDB\Category; 9use idoit\Api\Connection as ApiConnection; 10 11class syntax_plugin_idoit extends DokuWiki_Syntax_Plugin { 12 13 public function getType(){ return 'disabled'; } 14 public function getPType() { return 'block'; } 15 public function getAllowedTypes() { return array(); } 16 public function getSort(){ return 100; } 17 public function connectTo($mode) { $this->Lexer->addEntryPattern('<idoitAPI>(?=.*?</idoitAPI>)','base','plugin_idoit'); } 18 public function postConnect() { $this->Lexer->addExitPattern('</idoitAPI>','plugin_idoit'); } 19 20 21 function getInfo(){ 22 return array( 23 'author' => 'Oliver Günther', 24 'email' => 'mail@oliverguenther.de', 25 'date' => '2014-11-19', 26 'name' => 'i-doit API client plugin', 27 'desc' => 'Call i-doit API with JSON requests directly from DokuWiki', 28 'url' => 'https://github.com/oliverguenther/dokuwiki-idoit-syntax' 29 ); 30 } 31 32 33 /** 34 * Filter results with a given set of arrays, each containing 35 * one hierarchy element to access. 36 */ 37 function filterResults($request, $response) { 38 $results = array(); 39 40 foreach ($request['filter'] as $filter) { 41 // Every filter is an array of items 42 $obj = $response; 43 44 $path = $filter['path']; 45 $name = $filter['desc']; 46 foreach ($path as $elem) { 47 if (array_key_exists($elem, $obj)) { 48 // descend 49 $obj = $obj[$elem]; 50 } else { 51 // continue with next filter 52 $results[$name] = "Filter '$name' (path " . join('/', $path) . ") does not match response"; 53 continue 2; 54 } 55 } 56 $results[$name] = $obj; 57 } 58 59 return $results; 60 } 61 62 63 /** 64 * Execute the request on the JSON RPC apai 65 * and process the results. 66 */ 67 function callAPI($request) { 68 try { 69 70 // Init connection to api endpoint 71 $api_conn = new ApiClient(new ApiConnection( 72 $this->getConf('api_endpoint'), 73 $this->getConf('api_key'), 74 $this->getConf('api_user'), 75 $this->getConf('api_pass') 76 )); 77 78 $apiRequest = new Request($api_conn, $request['method'], $request['params']); 79 $response = $apiRequest->send(); 80 81 if ($request['filter']) { 82 return $this->filterResults($request, $response); 83 } else { 84 return $response; 85 } 86 87 88 89 } catch (Exception $e) { 90 return "API error: " . $e->getMessage(); 91 } 92 } 93 94 /** 95 * Parse the JSON request from the syntax environment 96 * and call the API with it. 97 * 98 * Returns a string error for JSON decode errors. 99 */ 100 function decodeAndRunQuery($request) { 101 102 $json = json_decode(trim($request), 1); 103 104 switch (json_last_error()) { 105 case JSON_ERROR_NONE: 106 return $this->callAPI($json); 107 case JSON_ERROR_DEPTH: 108 return 'JSON decode error: Maximum stack depth exceeded'; 109 case JSON_ERROR_STATE_MISMATCH: 110 return 'JSON decode error: Underflow or the modes mismatch'; 111 case JSON_ERROR_CTRL_CHAR: 112 return 'JSON decode error: Unexpected control character found'; 113 case JSON_ERROR_SYNTAX: 114 return 'JSON decode error: Syntax error, malformed JSON'; 115 case JSON_ERROR_UTF8: 116 return 'JSON decode error: Malformed UTF-8 characters, possibly incorrectly encoded'; 117 default: 118 return 'JSON decode error: unknown'; 119 } 120 } 121 122 123 public function handle($match, $state, $pos, Doku_Handler &$handler){ 124 switch ($state) { 125 case DOKU_LEXER_EXIT : 126 case DOKU_LEXER_ENTER : 127 break; 128 129 case DOKU_LEXER_UNMATCHED : 130 $result = $this->decodeAndRunQuery($match); 131 return array($state, $result); 132 } 133 134 return array($state, null); 135 } 136 137 public function render($mode, &$renderer, $data) { 138 if ($mode == 'xhtml') { 139 list($state, $match) = $data; 140 switch ($state) { 141 case DOKU_LEXER_ENTER : 142 $renderer->doc .= "<pre>"; 143 break; 144 145 case DOKU_LEXER_UNMATCHED : 146 if (is_array($match)) { 147 foreach ($match as $k => $v) { 148 if (!is_array($v)) { 149 // Print literal 150 $renderer->doc .= str_pad($k, 30) . "$v\n"; 151 } else { 152 // Print complex as print_r 153 $renderer->doc .= "--- $k ---\n"; 154 $renderer->doc .= print_r($v, true); 155 $renderer->doc .= "end $k end\n"; 156 } 157 } 158 } else { 159 $renderer->doc .= print_r($match, true); 160 } 161 162 break; 163 164 case DOKU_LEXER_EXIT : 165 $renderer->doc .= "</pre>"; 166 break; 167 } 168 return true; 169 } 170 return false; 171 } 172} 173