xref: /plugin/passwd/syntax.php (revision eb872c2a652d2b4294f9c5ebca2ba18675c61627)
1<?php
2if (!defined('DOKU_INC')) die();
3
4/**
5 * PASSWD Plugin: Renders a password-protected section with captcha verification.
6 *
7 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
8 * @author tomLin1998567
9 */
10class syntax_plugin_passwd extends DokuWiki_Syntax_Plugin
11{
12    public function getType()
13    {
14        return 'protected';
15    }
16
17    public function getPType()
18    {
19        return 'block';
20    }
21
22    public function getSort()
23    {
24        return 150;
25    }
26
27    public function connectTo($mode)
28    {
29        $this->Lexer->addSpecialPattern(
30            '<passwd\b[^>]*?>[\s\S]*?<\/passwd>',
31            $mode,
32            'plugin_passwd'
33        );
34    }
35
36    public function handle($match, $state, $pos, Doku_Handler $handler)
37    {
38        if (!preg_match('/^<passwd\b([^>]*?)>([\s\S]*?)<\/passwd>$/s', $match, $m)) {
39            return false;
40        }
41
42        $attrStr = $m[1];
43        $content = $m[2];
44
45        $attrs = array(
46            'password' => '',
47            'prompt'   => $this->getConf('prompt_text'),
48            'btn'      => $this->getConf('btn_text'),
49            'error'    => $this->getConf('error_text'),
50        );
51
52        if (preg_match('/password="([^"]+)"/i', $attrStr, $p)) $attrs['password'] = $p[1];
53        if (preg_match('/prompt="([^"]+)"/i',   $attrStr, $p)) $attrs['prompt']   = $p[1];
54        if (preg_match('/btn="([^"]+)"/i',      $attrStr, $p)) $attrs['btn']      = $p[1];
55        if (preg_match('/error="([^"]+)"/i',    $attrStr, $p)) $attrs['error']    = $p[1];
56
57        $attrs['content'] = $content;
58        return $attrs;
59    }
60
61    public function render($mode, Doku_Renderer $renderer, $data)
62    {
63        if ($mode != 'xhtml' || !$data) return false;
64
65        static $idx = 0;
66        $myIdx = $idx++;
67
68        $out  = '<div class="passwd_block" data-idx="' . $myIdx . '">';
69        $out .= '<form class="passwd_form">';
70        $out .= '<p class="passwd_prompt">' . hsc($data['prompt']) . '</p>';
71        $out .= '<div class="passwd_input_wrapper">';
72        $out .= '<input type="password" name="passwd" class="passwd_input" placeholder="Enter password">';
73        $out .= '<button type="button" class="passwd_toggle" onclick="passwd_toggle(this)" title="Show password">��</button>';
74        $out .= '</div>';
75        // Error message between input and button
76        $out .= '<span class="passwd_error" style="display:none">' . hsc($data['error']) . '</span>';
77        // Captcha placeholder — empty by design. A fresh captcha is fetched
78        // via AJAX on page load so cached HTML never contains stale tokens.
79        $out .= '<div class="passwd_captcha"></div>';
80        $out .= '<button type="submit" class="passwd_btn">' . hsc($data['btn']) . '</button>';
81        $out .= '</form>';
82        $out .= '<div class="passwd_content" style="display:none"></div>';
83        $out .= '</div>';
84
85        $renderer->doc .= $out;
86        return true;
87    }
88}
89