1<?php
2/**
3 * Gitlab Syntax Plugin: display Gitlab project
4 *
5 * @author Algorys
6 */
7
8if (!defined('DOKU_INC')) die();
9require 'gitlab/gitlab.php';
10
11class syntax_plugin_gitlabproject extends DokuWiki_Syntax_Plugin {
12    public function getType() {
13        return 'substition';
14    }
15
16    public function getPType() {
17        return 'normal';
18    }
19
20    function getAllowedTypes() {
21        return array('container', 'baseonly', 'substition','protected','disabled','formatting','paragraphs');
22    }
23
24    public function getSort() {
25        return 196;
26    }
27
28    function connectTo($mode) {
29        $this->Lexer->addSpecialPattern('<gitlab[^>]*/>', $mode, 'plugin_gitlabproject');
30    }
31
32   function getServerFromJson($server) {
33        $json_file = file_get_contents(__DIR__.'/server.json');
34        $json_data = json_decode($json_file, true);
35        if(isset($json_data[$server])) {
36            return $json_data[$server];
37        } else {
38            return null;
39        }
40    }
41
42    function handle($match, $state, $pos, Doku_Handler $handler) {
43        switch($state){
44            case DOKU_LEXER_SPECIAL :
45                // Init @data
46                $data = array(
47                    'state' => $state
48                );
49
50                // Match @server and @token
51                preg_match("/server *= *(['\"])(.*?)\\1/", $match, $server);
52                if (count($server) != 0) {
53                    $server_data = $this->getServerFromJson($server[2]);
54                    if (!is_null($server_data)) {
55                        $data['server'] = $server_data['url'];
56                        $data['token'] = $server_data['api_token'];
57                    }
58                }
59                if (!isset($data['server'])) {
60                    $data['server'] = $this->getConf('server.default');
61                }
62                if (!isset($data['token'])) {
63                    $data['token'] = $this->getConf('token.default');
64                }
65
66                // Match @project
67                preg_match("/project *= *(['\"])(.*?)\\1/", $match, $project);
68                if (count($project) != 0) {
69                    $data['project'] = $project[2];
70                }
71
72                return $data;
73            case DOKU_LEXER_UNMATCHED :
74                return array('state'=>$state, 'text'=>$match);
75            default:
76                return array('state'=>$state, 'bytepos_end' => $pos + strlen($match));
77        }
78    }
79
80    // Dokuwiki Renderer
81    function render($mode, Doku_Renderer $renderer, $data) {
82        if($mode != 'xhtml') return false;
83        if($data['error']) {
84            $renderer->doc .= $data['text'];
85            return true;
86        }
87
88        $renderer->info['cache'] = false;
89        switch($data['state']) {
90            case DOKU_LEXER_SPECIAL:
91                $this->renderGitlab($renderer, $data);
92                break;
93            case DOKU_LEXER_ENTER:
94            case DOKU_LEXER_EXIT:
95            case DOKU_LEXER_UNMATCHED:
96                $renderer->doc .= $renderer->_xmlEntities($data['text']);
97                break;
98        }
99        return true;
100    }
101
102    function renderGitlab($renderer, $data) {
103        // Gitlab object
104        $gitlab = new DokuwikiGitlab($data);
105
106        // Project
107        $project = $gitlab->getProject();
108        $project_url = $project['web_url'];
109        $project_name = $project['name'];
110        if(empty($project)) {
111            $this->renderProjectError($renderer, $data);
112            return array('state'=>$state, 'bytepos_end' => $pos + strlen($match));
113        }
114        $date_time = $this->getDateTime($project['last_activity_at']);
115        $namespace = $project['namespace']['name'];
116
117        // Members
118        $kind = $project['namespace']['kind'];
119        $unwanted_members = $this->getConf('unwanted.users');
120        $members = $gitlab->getProjectMembers($kind, $unwanted_members);
121        if(array_key_exists("message", $members)) {
122            $this->renderProjectError($renderer, $data);
123            return array('state'=>$state, 'bytepos_end' => $pos + strlen($match));
124        }
125
126        $img_url = DOKU_URL . 'lib/plugins/gitlabproject/images/gitlab.png';
127
128        // Renderer
129        $renderer->doc .= '<div class="gitlab">';
130        $renderer->doc .= '<span><img src="'.$img_url.'" class="gitlab"></span>';
131        $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.project').'</b><br>';
132        $renderer->doc .= '<hr class="gitlab">';
133        $renderer->doc .= '<a href="'.$project_url.'" class="gitlab">'.$project_name.'</a>';
134        $renderer->doc .= ' - <b>Namespace:</b> <a href="'.$data['server'].'/'.$namespace.'"> '.$namespace.'</a>';
135        $renderer->doc .= '<p><b>'.$this->getLang('gitlab.activity').':</b> '.$date_time['date'].' - '.$date_time['time'].'</p>';
136        $renderer->doc .= '<p><b>'.$this->getLang('gitlab.members').':</b>';
137        $total_members = count($members);
138        $i = 0;
139        foreach ($members as $key => $member) {
140            $i++;
141            $renderer->doc .= ' <a href="'.$member['web_url'].'">'.$member['username'].'</a> ';
142            $renderer->doc .= '('.$gitlab->getRoleName($member['access_level']).')';
143            if ($i != $total_members) $renderer->doc .= ',';
144        }
145        $renderer->doc .= '</p>';
146        $renderer->doc .= '</div>';
147
148        $gitlab->closeClient();
149    }
150
151    function renderProjectError($renderer, $data) {
152        // Renderer
153        $img_url = DOKU_URL . 'lib/plugins/gitlabproject/images/gitlab.png';
154        $renderer->doc .= '<div class="gitlab">';
155        $renderer->doc .= '<span><img src="'.$img_url.'" class="gitlab"></span>';
156        $renderer->doc .= '<b class="gitlab">'.$this->getLang('gitlab.project').'</b><br>';
157        $renderer->doc .= '<hr class="gitlab">';
158        $renderer->doc .= '<p>'.$this->getLang('gitlab.error').'</p>';
159        $renderer->doc .= '</div>';
160    }
161
162    function getDateTime($activity_time) {
163        $date_exploded = explode('T', $activity_time);
164        $time_exploded = explode('Z', $date_exploded[1]);
165
166        return array('date' => $date_exploded[0], 'time' => substr($time_exploded[0], 0, -4));
167    }
168}
169