1<?php 2/** 3 * Jira-links action plugin for DokuWiki 4 * 5 * This action adds Jira remote issue links when saving a page. 6 * 7 * @author christian studer <christian.studer@meteotest.ch> 8 * @license GPL2 http://www.gnu.org/licenses/gpl-2.0.html 9 */ 10 11// Must be run within DokuWiki 12if (!defined('DOKU_INC')) die(); 13 14/** 15 * The Jira-links action plugin itself 16 * 17 * @author christian studer <christian.studer@meteotest.ch> 18 */ 19class action_plugin_jiralinks extends DokuWiki_Action_Plugin { 20 /** 21 * Flag to detect double triggering of the event 22 * 23 * @var bool 24 */ 25 protected $alreadyTriggered = FALSE; 26 27 /** 28 * Register the IO_WIKIPAGE_WRITE AFTER event handler, if required 29 * 30 * @param Doku_Event_Handler $controller 31 */ 32 public function register(Doku_Event_Handler &$controller) { 33 if($this->getConf('enable_adding_urls_to_issues') and function_exists('curl_version')) { 34 $controller->register_hook('IO_WIKIPAGE_WRITE', 'AFTER', $this, 'addRemoteIssueLinks'); 35 } 36 37 } 38 39 /** 40 * Add remote issue links 41 * 42 * @param Doku_Event $event 43 * @param mixed $param 44 */ 45 public function addRemoteIssueLinks(Doku_Event &$event, $param) { 46 if($this->alreadyTriggered) return; 47 48 global $ID, $INFO, $conf; 49 50 // Look for issue keys 51 if(preg_match_all('/[A-Z]+?-[0-9]+/', $event->data[0][1], $keys)) { 52 // Keys found, prepare data for the remote issue link 53 $keys = array_unique($keys[0]); 54 $url = wl($ID, '', TRUE); 55 $globalId = md5($url); // MD5 hash is used because the global id max length is 255 characters. An effective page URL might be longer. 56 $applicationName = $conf['title']; 57 $applicationType = 'org.dokuwiki'; 58 $title = $applicationName . ' - ' . (empty($INFO['meta']['title']) ? $event->data[2] : $INFO['meta']['title']); 59 $relationship = $this->getConf('url_relationship'); 60 $favicon = tpl_getMediaFile(array(':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico'), TRUE); 61 62 foreach($keys as $key) { 63 // Prepare final data array 64 $data = array( 65 'globalId' => $globalId, 66 'application' => array( 67 'type' => $applicationType, 68 'name' => $applicationName, 69 ), 70 'relationship' => $relationship, 71 'object' => array( 72 'url' => $url, 73 'title' => $title, 74 'icon' => array( 75 'url16x16' => $favicon), 76 ), 77 ); 78 79 $this->executeRequest("issue/{$key}/remotelink", 'POST', $data); 80 } 81 82 $this->alreadyTriggered = TRUE; 83 } 84 } 85 86 /* 87 * Execute request 88 * 89 * @param string $request 90 * @param string $method 91 * @param array $data 92 * @return StdClass 93 */ 94 protected function executeRequest($request, $method = 'GET', $data = NULL) { 95 $curl = curl_init($this->getConf('jira_api_url') . $request); 96 97 // Additional curl setup 98 switch(strtoupper($method)) { 99 default: 100 case 'GET': 101 // Do nothing 102 break; 103 case 'POST': 104 curl_setopt($curl, CURLOPT_POST, TRUE); 105 106 // Send data 107 curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); 108 break; 109 } 110 111 // Basic curl setup 112 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 113 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); 114 curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC) ; 115 curl_setopt($curl, CURLOPT_USERPWD, $this->getConf('jira_api_username') . ':' . $this->getConf('jira_api_password')); 116 curl_setopt($curl, CURLOPT_TIMEOUT, 10); 117 curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 118 curl_setopt($curl, CURLOPT_HEADER, FALSE); 119 curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json")); 120 121 // Execution 122 $response = curl_exec($curl); 123 curl_close($curl); 124 125 return json_decode($response); 126 } 127} 128