1<?php
2/**
3 * syntax_plugin_tfsworkitemlink - provides a substitution for tfs work item links
4 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
5 * @author   Thorsten Klingert <Thorsten.Klingert@gmail.com>
6 */
7
8if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
9if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
10require_once(DOKU_PLUGIN.'syntax.php');
11
12class syntax_plugin_tfslink_workitemlink extends DokuWiki_Syntax_Plugin {
13
14    function getType(){ return 'substition'; }
15    function getSort(){ return 1; }
16
17    function connectTo($mode) {
18        $this->Lexer->addSpecialPattern('\[\[wi>.+?\]\]', $mode,'plugin_tfslink_workitemlink');
19    }
20
21    function handle($match, $state, $pos, Doku_Handler $handler) {
22        $data = array();
23
24        /* samples:
25         *  [[wi>#123]]
26         *  [[wi>#123|Title]]
27         *  [[wi>collection#123]]
28         *  [[wi>collection#123|Title]] */
29        if(!preg_match('/^\[\[wi>(?<cn>[^#>]*?)#(?<id>\d+)\s*(\|(?<title>.+?)|)\]\]$/m', $match, $options)) {
30            $data['error'] = '[invalid work item link format]'; // TODO: localize
31            return $data;
32        }
33        // extract options
34        //  - project collection (optional)
35        $collectionName = isset($options['cn']) ? trim($options['cn']) : '';
36        $collection = strlen($collectionName) == 0 // empty => use default collection
37            ? $this->_getDefaultProjectCollection()
38            : $this->_getProjectCollection($collectionName);
39        if (!isset($collection)){
40            $data['error'] = '[invalid/unknown project collection]'; // TODO: localize
41            return $data;
42        }
43        $data['projectCollection'] = $collection;
44        //  - identifier of the work item
45        $data['workItemId'] = intval($options['id']);
46        //  - title (optional)
47        $data['title'] = isset($options['title']) ? trim($options['title']) : '';
48        if (strlen($data['title']) == 0) // fallback to #id or [project collection title]#id for custom collections
49        {
50            if (isset($collection['title'])
51                    && ( strlen($collectionName) > 0 || $this->getConf('showdefaultcollectiontitle')))
52                $data['title'] = $collection['title'];
53            $data['title'] .= '#' . $options['id'];
54        }
55        // set tfs version
56        $data['version'] = isset($collection['version']) ? intval($collection['version']) : 2013; // fallback to 2013 by default.
57
58        return $data;
59    }
60    function render($mode, Doku_Renderer $renderer, $data) {
61        if($mode != 'xhtml') return false;
62
63        if (isset($data['error']))
64        {
65            $renderer->doc .= $data['error'];
66            return true;
67        }
68
69        $pcParamName = $data['version'] <= 2010 ? 'pguid' : 'pcguid';
70        $url = $data['projectCollection']['baseUrl'] . '/web/wi.aspx?';
71        $url .= $pcParamName . '=' . rawurlencode($data['projectCollection']['guid']);
72        $url .= '&id=' . $data['workItemId'];
73
74        $renderer->doc .= '<a href="' . $url. '" class="urlextern urltfsworkitem"';
75        $target = $this->getConf('linktarget');
76        if (isset($target)) {
77            $renderer->doc .= ' target="' . $target . '"';
78        }
79        $renderer->doc .= ' title="' . $url. '"';
80        $renderer->doc .= '>';
81        $renderer->doc .= $renderer->_xmlEntities($data['title']);
82        $renderer->doc .= '</a>';
83
84        return true;
85    }
86
87    private function _getDefaultProjectCollection()
88    {
89        $collection = $this->getConf('defaultCollection');
90        if(!isset($collection) || !is_array($collection)) {
91            if ($this->getConf('debug')) {
92                msg("TFSLink: default project collection not set or invalid.", -1);
93            }
94            return null;
95        }
96        return $collection;
97    }
98    private function _getProjectCollection($name)
99    {
100        $collections = $this->getConf('collections');
101        if(!isset($collections) || !is_array($collections)) {
102            if ($this->getConf('debug')) {
103                msg("TFSLink: unknown project collection: '". $name . "'. (No additional project collections defined)", -1);
104            }
105            return null;
106        }
107        if (!isset($collections[$name]) || !is_array($collections[$name])) {
108            if ($this->getConf('debug')) {
109                msg("TFSLink: unknown project collection: '". $name . "'. (No such project collection defined)", -1);
110            }
111            return;
112        }
113        return $collections[$name];
114    }
115}
116