1<?php 2// must be run within DokuWiki 3if(!defined('DOKU_INC')) die(); 4 5if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 6require_once DOKU_PLUGIN.'syntax.php'; 7 8class syntax_plugin_mantisreporter extends DokuWiki_Syntax_Plugin 9{ 10 /** 11 * @var int project id 12 */ 13 private $projectId; 14 15 /** 16 * Soap client if initialized. Else null. 17 * 18 * @var mixed Soap client 19 */ 20 private $soapClient = null; 21 22 /** 23 * get plugin type 24 * 25 * @return string 26 */ 27 public function getType() { 28 return 'substition'; 29 } 30 31 /** 32 * get sorting order 33 * 34 * @return int 35 */ 36 public function getSort() { 37 return 32; 38 } 39 40 /** 41 * Define matching strings 42 * 43 * @param string $mode 44 */ 45 public function connectTo($mode) { 46 $this->Lexer->addSpecialPattern('\{\{ mantisReport\?mantisProjectId=\d* }}', $mode, 'plugin_mantisreporter'); 47 } 48 49 /** 50 * set the parameters for $data for the render function 51 * 52 * @param string $match gematchte string 53 * @param int $state 54 * @param int $pos 55 * @param DokuHandler $handler 56 * 57 * @return array 58 */ 59 public function handle($match, $state, $pos, &$handler) { 60 return array($match, $state, $pos); 61 } 62 63 /** 64 * Render the report html 65 * 66 * @param string $format 67 * @param Doku_Renderer_metadata $renderer 68 * @param array $data 69 * 70 * @return type boolean is de operatie geslaagd? 71 */ 72 public function render($format, &$renderer, $data) { 73 74 if('xhtml' === $format) { 75 try { 76 $renderer->doc .= $this->saveIssue(); 77 } catch (Exception $e) { 78 print 'Er ging iets fout: ' . $e->getMessage(); 79 unset($_POST['reporter']); 80 } 81 try { 82 $this->parseData($data[0]); 83 $renderer->doc .= $this->getHtml(); 84 return true; 85 } catch (Exception $e) { 86 print 'Er ging iets fout: ' . $e->getMessage(); 87 return false; 88 } 89 } else { 90 return false; 91 } 92 } 93 94 /** 95 * Parse data to filter out variables 96 * 97 * @param string $data 98 * 99 * @return boolean success 100 */ 101 private function parseData($data) { 102 $regexId = '#mantisProjectId=(\d*)#i'; 103 $resultId = array(); 104 preg_match($regexId, $data, $resultId); 105 $this->setProjectId($resultId[1]); 106 return true; 107 } 108 109 /** 110 * Get the project id 111 * 112 * @return int 113 */ 114 private function getProjectId() { 115 return $this->projectId; 116 } 117 118 /** 119 * Set the project id 120 * 121 * @param int $projectId 122 */ 123 private function setProjectId($projectId) { 124 $this->projectId = $projectId; 125 } 126 127 /** 128 * Get the html for priorities 129 * 130 * @return string 131 */ 132 private function getPrioritiesHtml() { 133 $html = "<select name='priority'>"; 134 $priorities = $this->getPriorities(); 135 136 if(0 === count($priorities)) { 137 return 'Geen prioriteiten gevonden'; 138 } 139 140 foreach($priorities as $priority) { 141 $html .= '<option '; 142 if($priority->id == 30) { 143 $html .= 'selected '; 144 } 145 $html .= 'value="'.$priority->id.'">'.$priority->name.'</option>'; 146 } 147 return $html . '</select>'; 148 } 149 150 /** 151 * Get the html for reporters 152 * 153 * @return string 154 */ 155 private function getReportersHtml() { 156 $caller = $_GET['caller']; 157 $html = "<select name='reporter'>"; 158 $reporters = $this->getReporters(); 159 if(0 === count($reporters)) { 160 return 'Geen reporters gevonden'; 161 } 162 foreach($reporters as $reporter) { 163 $html .= '<option value="'.$reporter->id . '"'; 164 165 if($reporter->name === $caller) { 166 $html .= ' selected=selected '; 167 } 168 $html .= '>'.$reporter->real_name.'</option>'; 169 } 170 return $html . '</select>'; 171 } 172 173 /** 174 * Get the html for categories 175 * 176 * @return string 177 */ 178 private function getCategoriesHtml() { 179 $html = "<select name='category'>"; 180 $categories = $this->getCategories(); 181 if(0 === count($categories)) { 182 return 'Geen categorieën gevonden'; 183 } 184 foreach($categories as $category) { 185 $html .= '<option value="'.$category.'">'.$category.'</option>'; 186 } 187 return $html . '</select>'; 188 } 189 190 /** 191 * Get the html 192 * 193 * @return string 194 */ 195 private function getHtml() { 196 $priorities = $this->getPrioritiesHtml(); 197 $reporters = $this->getReportersHtml(); 198 $categories = $this->getCategoriesHtml(); 199 $prognose = $this->getPrognoseHtml(); 200 $projectId = $this->getProjectId(); 201 $str = <<<EOD 202<form method='POST'> 203<input type='hidden' name='projectId' value='$projectId' /> 204 <table class='mantisreporter'> 205 <tr> 206 <td>reporter</td> 207 <td>categorie</td> 208 <td>prioriteit</td> 209 </tr> 210 <tr> 211 <td> 212 $reporters 213 </td> 214 <td> 215 $categories 216 </td> 217 <td> 218 $priorities 219 </td> 220 </tr> 221 <tr> 222 <td colspan='5'>samenvatting</td> 223 </tr> 224 <tr> 225 <td colspan='5'> 226 <input type='text' name='summary' class='summary' required /> 227 </td> 228 </tr> 229 <tr> 230 <td colspan='5'>omschrijving</td> 231 </tr> 232 <tr> 233 <td colspan='5'> 234 <textarea name='description' required></textarea> 235 </td> 236 </tr> 237 <tr> 238 <td colspan='5' class='submit'> 239 $prognose <input type='submit' value='ticket aanmaken' /> 240 </td> 241 </tr> 242 </table> 243</form> 244EOD; 245 return $str; 246 } 247 248 /** 249 * Get all priorities 250 * 251 * @return string 252 */ 253 private function getPriorities() { 254 return $this->callSoapClient('mc_enum_priorities'); 255 } 256 257 /** 258 * Get all possible reporters for this project 259 * access 25 means reporters and higher 260 * 261 * @return string 262 */ 263 private function getReporters() { 264 $reporters = $this->callSoapClient('mc_project_get_users', array('project_id' => (int) $this->getProjectId(), 'access' => 25)); 265 foreach($reporters as $key => $reporter) { 266 if($reporter->name === 'SoapUser') { 267 unset($reporters[$key]); 268 } 269 } 270 return $reporters; 271 } 272 273 /** 274 * Get all possible reporters for this project 275 * 276 * @return string 277 */ 278 private function getCategories() { 279 return $this->callSoapClient('mc_project_get_categories', array('project_id' => (int) $this->getProjectId())); 280 } 281 282 /** 283 * Get all possible custom fields for this project 284 * 285 * @return string 286 */ 287 private function getCustomFields($projectId = null) { 288 if($projectId === null) { 289 $projectId = $this->getProjectId(); 290 } 291 return $this->callSoapClient('mc_project_get_custom_fields', array('project_id' => (int) $projectId)); 292 } 293 294 /** 295 * Get html for prognose (if available for this project). 296 * 297 * @return string 298 */ 299 private function getPrognoseHtml() { 300 foreach($this->getCustomFields() as $customField) { 301 if('prognose' === $customField->field->name) { 302 return 'prognose <input type="text" min="0" name="prognose" class="prognose-input" required /> uur'; 303 } 304 } 305 return ''; 306 } 307 308 private function getPrognoseId($projectId) { 309 foreach($this->getCustomFields($projectId) as $customField) { 310 if('prognose' === $customField->field->name) { 311 return $customField->field->id; 312 } 313 } 314 return ''; 315 } 316 317 /** 318 * Get the soap client 319 * 320 * @return SoapClient 321 */ 322 private function getSoapClient() { 323 if($this->soapClient === null) { 324 ini_set('default_socket_timeout', 5); 325 $this->soapClient = new SoapClient($this->getMantisUrl() . '/api/soap/mantisconnect.php?wsdl', array("connection_timeout"=>5)); 326 } 327 328 return $this->soapClient; 329 } 330 331 /** 332 * Send a request to the soap client 333 * 334 * @param string $function what function should be called? 335 * @param array $array extra parameters 336 * 337 * @return mixed result from the request. 338 */ 339 private function callSoapClient($function, $array = array()) { 340 $sc = $this->getSoapClient(); 341 $parameters = array('username' => $this->getConf('soap_user'), 'password' => $this->getConf('soap_password')); 342 foreach($array as $key => $value) { 343 $parameters[$key] = $value; 344 } 345 $returnValue = $sc->__call($function, $parameters, array()); 346 return $returnValue; 347 } 348 349 /** 350 * Save issue 351 * 352 * @return string HTML with a link to the issue. 353 */ 354 private function saveIssue() { 355 if(isset($_POST['reporter'])) { 356 $newIssue = new stdClass(); 357 358 $newIssue->reporter = new stdClass(); 359 $newIssue->reporter->id = (int) $_POST['reporter']; 360 361 $newIssue->priority = new stdClass(); 362 $newIssue->priority->id = (int) $_POST['priority']; 363 364 $newIssue->project = new stdClass(); 365 $newIssue->project->id = (int) $_POST['projectId']; 366 367 $newIssue->category = $_POST['category']; 368 $newIssue->summary = $_POST['summary']; 369 $newIssue->description = $_POST['description']; 370 371 if($_POST['prognose']) { 372 $prognose = new stdClass(); 373 $prognose->field = new stdClass(); 374 $prognose->field->id = $this->getPrognoseId($_POST['projectId']); 375 $prognose->field->name = 'prognose'; 376 377 $prognose->value = (float) $_POST['prognose']; 378 $newIssue->custom_fields = array( 379 $prognose 380 ); 381 } 382 $newIssueId = $this->callSoapClient('mc_issue_add', array('issue' => $newIssue)); 383 unset($_POST['reporter']); 384 return 'Nieuw issue aangemaakt: <a href="'.$this->getMantisUrl().'/view.php?id=' . $newIssueId . '">' . $newIssueId . '</a><br><br>'; 385 } 386 } 387 388 /** 389 * Get the mantis Url 390 * 391 * @return string 392 */ 393 private function getMantisUrl() { 394 return $this->getConf('soap_url'); 395 } 396 397 398 399 400 401 402 // configuration methods 403 /** 404 * getConf($setting) 405 * 406 * use this function to access plugin configuration variables 407 */ 408 function getConf($setting){ 409 410 if (!$this->configloaded){ $this->loadConfig(); } 411 412 return $this->conf[$setting]; 413 } 414 415 /** 416 * loadConfig() 417 * merges the plugin's default settings with any local settings 418 * this function is automatically called through getConf() 419 */ 420 function loadConfig(){ 421 global $conf; 422 423 $defaults = $this->readDefaultSettings(); 424 $plugin = $this->getPluginName(); 425 426 foreach ($defaults as $key => $value) { 427 if (isset($conf['plugin'][$plugin][$key])) continue; 428 $conf['plugin'][$plugin][$key] = $value; 429 } 430 431 $this->configloaded = true; 432 $this->conf =& $conf['plugin'][$plugin]; 433 } 434 435 /** 436 * read the plugin's default configuration settings from conf/default.php 437 * this function is automatically called through getConf() 438 * 439 * @return array setting => value 440 */ 441 function readDefaultSettings() { 442 443 $path = DOKU_PLUGIN.$this->getPluginName().'/conf/'; 444 $conf = array(); 445 446 if (@file_exists($path.'default.php')) { 447 include($path.'default.php'); 448 } 449 450 return $conf; 451 } 452 453}