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
20    /**
21     * @return string Syntax mode type
22     */
23    public function getType()
24    {
25        return 'substition';
26    }
27
28    /**
29     * @return string Paragraph type
30     */
31    public function getPType()
32    {
33		return 'normal';
34    }
35
36    /**
37     * @return int Sort order - Low numbers go before high numbers
38     */
39    public function getSort()
40    {
41        return 55;
42    }
43
44    /**
45     * Connect lookup pattern to lexer.
46     *
47     * @param string $mode Parser mode
48     */
49    public function connectTo($mode)
50    {
51        $this->Lexer->addSpecialPattern('{{hash>.+?}}', $mode, 'plugin_odtsupport');
52        $this->Lexer->addSpecialPattern('{{pagehash}}', $mode, 'plugin_odtsupport');
53        $this->Lexer->addSpecialPattern('{{pagehash4}}', $mode, 'plugin_odtsupport');
54        $this->Lexer->addSpecialPattern('{{'.$this->odt_field_pagehash.'>.+?}}', $mode, 'plugin_odtsupport');
55        $this->Lexer->addSpecialPattern('{{'.$this->odt_field_pagehash4.'>.+?}}', $mode, 'plugin_odtsupport');
56        $this->Lexer->addSpecialPattern('{{'.$this->odt_field_metadata.'>.+?}}', $mode, 'plugin_odtsupport');
57    }
58
59    /**
60     * Handle matches of the odtsupport syntax
61     *
62     * @param string       $match   The match of the syntax
63     * @param int          $state   The state of the handler
64     * @param int          $pos     The position in the document
65     * @param Doku_Handler $handler The handler
66     *
67     * @return array Data for the renderer
68     */
69    public function handle($match, $state, $pos, Doku_Handler $handler)
70    {
71		if (preg_match('/{{([a-zA-Z0-9]+)/', $match, $matches) !== 1) {
72			return array();
73		}
74		// Der erste Match sollte genau ein Wort sein, das nach '{{' im String $match steht.
75		$command = $matches[1];
76
77		$pageid = pageinfo()['id'];
78		$hash = hash(hash_hmac_algos()[0], $pageid);
79
80		switch ($command) {
81			case "hash":
82				$string = substr($match, 7, -2); //strip markup
83				$hash = hash(hash_hmac_algos()[0], $string);
84				break;
85			case "pagehash4":
86				$hash = substr($hash,0,4);
87				break;
88			case "pagehash":
89				break;
90			case $this->odt_field_pagehash4:
91				$string = substr($match, strlen($this->odt_field_pagehash4)+3, -2); //strip markup
92				$hash = substr($hash,0,4);
93				break;
94			case $this->odt_field_pagehash:
95				$string = substr($match, strlen($this->odt_field_pagehash)+3, -2); //strip markup
96				break;
97			case $this->odt_field_metadata:
98				$string = substr($match, strlen($this->odt_field_metadata)+3, -2); //strip markup
99
100				$metadata = p_get_metadata($pageid, $string, METADATA_RENDER_USING_CACHE);
101
102				// check if the given string contains 'date'
103				if (strpos($string,'date') !== false) {
104					// convert the given date to a date string
105					$hash = date($this->getConf('dateformat'), intval($metadata));
106				} else {
107					// take the raw data
108					$hash = $metadata;
109				}
110
111				break;
112		}
113
114		return array($command,$string,$hash);
115    }
116
117    /**
118     * Render xhtml output or metadata
119     *
120     * @param string        $mode     Renderer mode (supported modes: xhtml)
121     * @param Doku_Renderer $renderer The renderer
122     * @param array         $data     The data from the handler() function
123     *
124     * @return bool If rendering was successful.
125     */
126    public function render($mode, Doku_Renderer $renderer, $data)
127    {
128        list($command, $string, $hash) = $data;
129
130        if ($mode == 'xhtml') {
131            if ($command != $this->odt_field_pagehash4
132			&& $command != $this->odt_field_pagehash
133			&& $command != $this->odt_field_metadata) {
134				$renderer->doc .= $hash;
135			}
136			return true;
137        } elseif ($mode == 'text') {
138			// make the hash code searchable (usage of plugins searchtext and text necessary!)
139			if ($command != $this->odt_field_metadata) { // don't insert metadata - if this should be searchable, it may be printed onto the page
140				$renderer->doc .= $hash;
141				return true;
142			}
143        } elseif ($mode == 'odt') {
144            if ($command == $this->odt_field_pagehash4
145			|| $command == $this->odt_field_pagehash
146			|| $command == $this->odt_field_metadata) {
147				$fieldsPlugin = $this->loadHelper('fields');
148				if ($fieldsPlugin) {
149					$fieldsPlugin->ODTSetUserField($renderer, $string, $renderer->_xmlEntities($hash));
150				}
151			}
152			return true;
153        }
154
155        return true;
156    }
157}
158
159