1<?php
2/**
3 * DokuWiki Plugin odtsupport (Syntax Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Thomas Schäfer <thomas.schaefer@itschert.net>
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) {
11    die();
12}
13
14class syntax_plugin_odtsupport extends DokuWiki_Syntax_Plugin
15{
16	private $odt_field_pagehash4 = 'pagehash4tofield';
17	private $odt_field_pagehash = 'pagehashtofield';
18	private $odt_field_metadata = 'metadatatofield';
19	private $serverurl = 'serverurl';
20
21
22    /**
23     * @return string Syntax mode type
24     */
25    public function getType()
26    {
27        return 'substition';
28    }
29
30    /**
31     * @return string Paragraph type
32     */
33    public function getPType()
34    {
35		return 'normal';
36    }
37
38    /**
39     * @return int Sort order - Low numbers go before high numbers
40     */
41    public function getSort()
42    {
43        return 55;
44    }
45
46    /**
47     * Connect lookup pattern to lexer.
48     *
49     * @param string $mode Parser mode
50     */
51    public function connectTo($mode)
52    {
53        $this->Lexer->addSpecialPattern('{{hash>[-.:\d\w]+?}}', $mode, 'plugin_odtsupport');
54        $this->Lexer->addSpecialPattern('{{hash4>[-.:\d\w]+?}}', $mode, 'plugin_odtsupport');
55        $this->Lexer->addSpecialPattern('{{pagehash}}', $mode, 'plugin_odtsupport');
56        $this->Lexer->addSpecialPattern('{{pagehash4}}', $mode, 'plugin_odtsupport');
57        $this->Lexer->addSpecialPattern('{{'.$this->odt_field_pagehash.'>.+?}}', $mode, 'plugin_odtsupport');
58        $this->Lexer->addSpecialPattern('{{'.$this->odt_field_pagehash4.'>.+?}}', $mode, 'plugin_odtsupport');
59        $this->Lexer->addSpecialPattern('{{'.$this->odt_field_metadata.'>.+?}}', $mode, 'plugin_odtsupport');
60        $this->Lexer->addSpecialPattern('{{'.$this->serverurl.'>.*?:.+?}}', $mode, 'plugin_odtsupport');
61    }
62
63    /**
64     * Handle matches of the odtsupport syntax
65     *
66     * @param string       $match   The match of the syntax
67     * @param int          $state   The state of the handler
68     * @param int          $pos     The position in the document
69     * @param Doku_Handler $handler The handler
70     *
71     * @return array Data for the renderer
72     */
73    public function handle($match, $state, $pos, Doku_Handler $handler)
74    {
75		if (preg_match('/{{([a-zA-Z0-9]+)/', $match, $matches) !== 1) {
76			return array();
77		}
78		// Der erste Match sollte genau ein Wort sein, das nach '{{' im String $match steht.
79		$command = $matches[1];
80
81		$pageid = pageinfo()['id'];
82		$hash = hash(hash_hmac_algos()[0], $pageid);
83		$string = "";
84		$string2 = "";
85
86		switch ($command) {
87			case "hash":
88				$string = substr($match, 7, -2); //strip markup
89				$hash = hash(hash_hmac_algos()[0], $string);
90				break;
91			case "hash4":
92				$string = substr($match, 8, -2); //strip markup
93				$hash = hash(hash_hmac_algos()[0], $string);
94				$hash = substr($hash,0,4);
95				break;
96			case "pagehash4":
97				$hash = substr($hash,0,4);
98				break;
99			case "pagehash":
100				break;
101			case $this->serverurl:
102				$params = substr($match, strlen($this->serverurl)+3, -2); //strip markup
103				$params = str_replace("<PAGEHASH>",$hash,$params); // replace "<PAGEHASH>" keyword by hash
104				$hash = substr($hash,0,4);
105				$params = str_replace("<PAGEHASH4>",$hash,$params); // replace "<PAGEHASH4>" keyword by hash
106				list($string,$string2) = explode(":",$params);
107				break;
108			case $this->odt_field_pagehash4:
109				$string = substr($match, strlen($this->odt_field_pagehash4)+3, -2); //strip markup
110				$hash = substr($hash,0,4);
111				break;
112			case $this->odt_field_pagehash:
113				$string = substr($match, strlen($this->odt_field_pagehash)+3, -2); //strip markup
114				break;
115			case $this->odt_field_metadata:
116				$string = substr($match, strlen($this->odt_field_metadata)+3, -2); //strip markup
117
118				$metadata = p_get_metadata($pageid, $string, METADATA_RENDER_USING_CACHE);
119
120				// check if the given string contains 'date'
121				if (strpos($string,'date') !== false) {
122					// convert the given date to a date string
123					$hash = date($this->getConf('dateformat'), intval($metadata));
124				} else {
125					// take the raw data
126					$hash = $metadata;
127				}
128
129				break;
130		}
131
132		return array($command,$string,$hash,$string2);
133    }
134
135    /**
136     * Render xhtml output or metadata
137     *
138     * @param string        $mode     Renderer mode (supported modes: xhtml)
139     * @param Doku_Renderer $renderer The renderer
140     * @param array         $data     The data from the handler() function
141     *
142     * @return bool If rendering was successful.
143     */
144    public function render($mode, Doku_Renderer $renderer, $data)
145    {
146        list($command, $string, $hash, $string2) = $data;
147
148        if ($mode == 'xhtml') {
149            if ($command == $this->serverurl) {
150				$url = $this->getConf('serverurl').$string;
151				$renderer->doc .= "<a class='windows' href='".$url."'>".$string2."</a>";
152			} else if ($command != $this->odt_field_pagehash4
153					&& $command != $this->odt_field_pagehash
154					&& $command != $this->odt_field_metadata) {
155				$renderer->doc .= $hash;
156			}
157			return true;
158        } elseif ($mode == 'text') {
159			// make the hash code searchable (usage of plugins searchtext and text necessary!)
160			if ($command != $this->odt_field_metadata) { // don't insert metadata - if this should be searchable, it may be printed onto the page
161				$renderer->doc .= $hash;
162				return true;
163			}
164        } elseif ($mode == 'odt') {
165			if ($command == $this->serverurl) {
166				$url = $this->getConf('serverurl').$string;
167
168				// TODO: implement odt output
169
170			} else if ($command == $this->odt_field_pagehash4
171			|| $command == $this->odt_field_pagehash
172			|| $command == $this->odt_field_metadata) {
173				$fieldsPlugin = $this->loadHelper('fields');
174				if ($fieldsPlugin && $this->getConf('firstdefinitionwins')) {
175                    $usecounter_helper = plugin_load('helper','usecounter');
176
177                    if ($usecounter_helper && $usecounter_helper->amountOfUses('odtsupport_'.$command) == 0) {
178                        $fieldsPlugin->ODTSetUserField($renderer, $string, $renderer->_xmlEntities($hash));
179                        $usecounter_helper->incUsageOf('odtsupport_'.$command);
180                    }
181
182				}
183			}
184			return true;
185        }
186
187        return true;
188    }
189}
190
191