1<?php 2/** 3 * GitLab Api Plugin 4 * 5 * @license : BSD-3 Clause 6 * @author : Mehmet Ozgan <mozgan@gmail.com> 7 */ 8 9if (!defined('DOKU_INC')) die(); 10 11require __DIR__.'/gitlab/gitlabapi.php'; 12 13class syntax_plugin_gitlabapi extends DokuWiki_Syntax_Plugin { 14 /** 15 * Syntax Plugins 16 * 17 * The class needs to implement at least the following functions: 18 * -) getType() 19 * -) getSort() 20 * -) connectTo($mode) 21 * -) handle($match, $state, $pos, Doku_Handler $handler) 22 * -) render($mode, Doku_Renderer $renderer, $data) 23 * 24 * More information: https://www.dokuwiki.org/devel:syntax_plugins#syntax_types 25 */ 26 27 public function getType() { return 'substition'; } 28 29 public function getPType() { return 'normal'; } 30 31 public function getSort() { return 196; } 32 33 public function connectTo($mode) { 34 $this->Lexer->addSpecialPattern('<gitlab-api[^>]*/>', $mode, 'plugin_gitlabapi'); 35 } 36 37 function getServerFromJson($server) { 38 $json_file = file_get_contents(__DIR__.'/server.json'); 39 $json_data = json_decode($json_file, true); 40 if (isset($json_data[$server])) 41 return $json_data[$server]; 42 else 43 return null; 44 } 45 46 47 function handle($match, $state, $pos, Doku_Handler $handler) { 48 switch ($state) { 49 case DOKU_LEXER_SPECIAL: 50 $data = array( 51 'state' => $state 52 ); 53 54 // match @server and @token 55 preg_match("/server *= *(['\"])(.*?)\\1/", $match, $server); 56 if (count($server) != 0) { 57 $server_data = $this->getServerFromJson($server[2]); 58 if (!is_null($server_data)) { 59 $data['server'] = $server_data['url']; 60 $data['token'] = $server_data['api_token']; 61 } 62 } 63 if (!isset($data['server'])) 64 $data['server'] = $this->getConf('server.default'); 65 if (!isset($data['token'])) 66 $data['token'] = $this->getConf('token.default'); 67 68 // match @project-path 69 preg_match("/project-path *= *(['\"])(.*?)\\1/", $match, $project_path); 70 if (count($project_path) != 0) 71 $data['project-path'] = $project_path[2]; 72 73 // match @milestones 74 preg_match("/milestones *= *(['\"])(.*?)\\1/", $match, $milestones); 75 $data['milestones'] = $milestones[2]; 76 77 // match @commits 78 preg_match("/commits *= *(['\"])(.*?)\\1/", $match, $commits); 79 $data['commits'] = $commits[2]; 80 81 // match @issues 82 preg_match("/issues *= *(['\"])(.*?)\\1/", $match, $issues); 83 $data['issues'] = $issues[2]; 84 85 // match @pipelines 86 preg_match("/pipelines *= *(['\"])(.*?)\\1/", $match, $pipelines); 87 $data['pipelines'] = $pipelines[2]; 88 89 return $data; 90 91 case DOKU_LEXER_UNMATCHED: 92 return array('state' => $state, 'text' => $match); 93 94 default: 95 return array('state' => $state, 'bytepos_end' => $pos + strlen($match)); 96 } 97 } 98 99 function render($mode, Doku_Renderer $renderer, $data) { 100 if ($mode !== 'xhtml') return false; 101 if ($mode != 'xhtml') return false; 102 103 if ($data['error']) { 104 $renderer->doc .= $data['text']; 105 return true; 106 } 107 108 $renderer->info['cache'] = false; 109 switch ($data['state']) { 110 case DOKU_LEXER_SPECIAL: 111 $this->renderGitLab($renderer, $data); 112 break; 113 114 case DOKU_LEXER_ENTER: 115 case DOKU_LEXER_EXIT: 116 case DOKU_LEXER_UNMATCHED: 117 $renderer->doc .= $renderer->_xmlEntities($data['text']); 118 break; 119 } 120 121 return true; 122 } 123 124 function renderGitLab($renderer, $data) { 125 // create GitLabApi object 126 $gitlab = new GitLabApi($data); 127 128 // get project 129 $project = $gitlab->getProject(); 130 //dbg($project); 131 132 if (empty($project)) { 133 $this->renderProjectError($renderer, $data); 134 return array('state' => $state, 'bytepos_end' => $pos + strlen($match)); 135 } 136 137 $project_id = $project['id']; 138 139 $project_url = $project['web_url']; 140 $project_name = $project['name']; 141 $date_time = $this->getDateTime($project['last_activity_at']); 142 $namespace = $project['namespace']['full_path']; 143 144 $img_url = DOKU_URL . 'lib/plugins/gitlabapi/images/gitlab.png'; 145 146 $renderer->doc .= '<div class="gitlab">'; 147 $renderer->doc .= '<span><img src="'.$img_url.'" class="gitlab"></span>'; 148 $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.project').'</b><br>'; 149 $renderer->doc .= '<hr class="gitlab">'; 150 $renderer->doc .= '<a href="'.$project_url.'" class="gitlab">'.$project_name.'</a>'; 151 $renderer->doc .= ' - <b>Namespace:</b> <a href="'.$data['server'].'/'.$namespace.'"> '.$namespace.'</a>'; 152 $renderer->doc .= '<p><b>'.$this->getLang('gitlab.activity').':</b> '.$date_time['date'].' - '.$date_time['time'].'</p>'; 153 154 if ($data['milestones']) 155 $this->renderProjectMilestones($renderer, $gitlab, $project_id, $data['milestones']); 156 if ($data['commits']) 157 $this->renderProjectCommits($renderer, $gitlab, $project_id, $data['commits']); 158 if ($data['issues']) 159 $this->renderProjectIssues($renderer, $gitlab, $project_id, $data['issues']); 160 if ($data['pipelines']) 161 $this->renderProjectPipelines($renderer, $gitlab, $project_id, $data['pipelines']); 162 163 $renderer->doc .= '</p>'; 164 $renderer->doc .= '</div>'; 165 166 $gitlab->closeClient(); 167 } 168 169 function renderProjectCommits($renderer, $gitlab, $project_id, $number) { 170 $commits = $gitlab->getCommits($project_id); 171 172 $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.commits').'</b><br>'; 173 $renderer->doc .= '<table border="1"> 174 <thread> 175 <tr> 176 <th>Committer Name</th> 177 <th>Title</th> 178 <th>Message</th> 179 <th>Date</th> 180 <th>URL</th> 181 <tr> 182 </thread> 183 <tbody>'; 184 185 $total = count($commits) < $number ? count($commits) : $number; 186 for ($i = 0; $i < $total; $i++) { 187 $renderer->doc .= '<tr>'; 188 $renderer->doc .= '<td>'.$commits[$i]['committer_name'].'</td>'; 189 $renderer->doc .= '<td>'.$commits[$i]['title'].'</td>'; 190 $renderer->doc .= '<td>'.$commits[$i]['message'].'</td>'; 191 $renderer->doc .= '<td>'.$commits[$i]['committed_date'].'</td>'; 192 $renderer->doc .= '<td><a href='.$commits[$i]['web_url'].'>Commit link</a></td>'; 193 $renderer->doc .= '</tr>'; 194 } 195 $renderer->doc .= '</tbody></table>'; 196 } 197 198 function renderProjectIssues($renderer, $gitlab, $project_id, $number) { 199 $issues = $gitlab->getIssues($project_id); 200 201 $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.issues').'</b><br>'; 202 $renderer->doc .= '<table border="1"> 203 <thread> 204 <tr> 205 <th>Author</th> 206 <th>Title</th> 207 <th>Labels</th> 208 <th>Assignees</th> 209 <th>State</th> 210 <th>URL</th> 211 <tr> 212 </thread> 213 <tbody>'; 214 215 $total = count($issues) < $number ? count($issues) : $number; 216 for ($i = 0; $i < $total; $i++) { 217 $renderer->doc .= '<tr>'; 218 $renderer->doc .= '<td>'.$issues[$i]['author']['name'].'</td>'; 219 $renderer->doc .= '<td>'.$issues[$i]['title'].'</td>'; 220 $labels = $issues[$i]['labels']; 221 $l_list = ''; 222 foreach ($labels as $l) 223 $l_list .= $l.', '; 224 $renderer->doc .= '<td>'.rtrim($l_list,', ').'</td>'; 225 $assignees = $issues[$i]['assignees']; 226 $a_list = ''; 227 foreach ($assignees as $a) 228 $a_list .= $a['name'].', '; 229 $renderer->doc .= '<td>'.rtrim($a_list, ', ').'</td>'; 230 $renderer->doc .= '<td>'.$issues[$i]['state'].'</td>'; 231 $renderer->doc .= '<td><a href='.$issues[$i]['web_url'].'>Issue link</a></td>'; 232 $renderer->doc .= '</tr>'; 233 } 234 $renderer->doc .= '</tbody></table>'; 235 236 } 237 238 function renderProjectMilestones($renderer, $gitlab, $project_id, $number) { 239 $milestones = $gitlab->getMilestones($project_id); 240 241 $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.milestones').'</b><br>'; 242 $renderer->doc .= '<table border="1"> 243 <thread> 244 <tr> 245 <th>Title</th> 246 <th>Description</th> 247 <th>State</th> 248 <th>Created</th> 249 <th>URL</th> 250 <tr> 251 </thread> 252 <tbody>'; 253 254 $total = count($milestones) < $number ? count($milestones) : $number; 255 for ($i = 0; $i < $total; $i++) { 256 $renderer->doc .= '<tr>'; 257 $renderer->doc .= '<td>'.$milestones[$i]['title'].'</td>'; 258 $renderer->doc .= '<td>'.$milestones[$i]['description'].'</td>'; 259 $renderer->doc .= '<td>'.$milestones[$i]['state'].'</td>'; 260 $renderer->doc .= '<td>'.$milestones[$i]['created_at'].'</td>'; 261 $renderer->doc .= '<td><a href='.$milestones[$i]['web_url'].'>Milestone link</a></td>'; 262 $renderer->doc .= '</tr>'; 263 } 264 265 $renderer->doc .= '</tbody></table>'; 266 } 267 268 function renderProjectPipelines($renderer, $gitlab, $project_id, $number) { 269 $pipelines = $gitlab->getPipelines($project_id); 270 271 $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.pipelines').'</b><br>'; 272 $renderer->doc .= '<table border="1"> 273 <thread> 274 <tr> 275 <th>Ref</th> 276 <th>Status</th> 277 <th>Source</th> 278 <th>URL</th> 279 <tr> 280 </thread> 281 <tbody>'; 282 283 $total = count($pipelines) < $number ? count($pipelines) : $number; 284 for ($i = 0; $i < $total; $i++) { 285 $renderer->doc .= '<tr>'; 286 $renderer->doc .= '<td>'.$pipelines[$i]['ref'].'</td>'; 287 $renderer->doc .= '<td>'.$pipelines[$i]['status'].'</td>'; 288 $renderer->doc .= '<td>'.$pipelines[$i]['source'].'</td>'; 289 $renderer->doc .= '<td><a href='.$pipelines[$i]['web_url'].'>Pipeline link</a></td>'; 290 $renderer->doc .= '</tr>'; 291 } 292 293 $renderer->doc .= '</tbody></table>'; 294 295 } 296 297 function renderProjectError($renderer, $data) { 298 $img_url = DOKU_URL . 'lib/plugins/gitlabapi/images/gitlab.png'; 299 300 $renderer->doc .= '<div class="gitlab">'; 301 $renderer->doc .= '<span><img src="'.$img_url.'" class="gitlab"></span>'; 302 $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.project').'</b><br>'; 303 $renderer->doc .= '<hr class="gitlab">'; 304 $renderer->doc .= '<p>'.$this->getLang('gitlab.error').'</p>'; 305 $renderer->doc .= '</div>'; 306 } 307 308 function getDateTime($activity_time) { 309 $date_exploded = explode('T', $activity_time); 310 $time_exploded = explode('Z', $date_exploded[1]); 311 312 return array('date' => $date_exploded[0], 'time' => substr($time_exploded[0], 0, -4)); 313 } 314 315} 316 317 318 319