1<?php
2/**
3 * Plugin DokuCrypt2: Enables client side encryption
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Scott Moser <smoser@brickies.net>, Maintainer Sherri W. ( contact me at syntaxseed.com)
7 */
8
9// must be run within Dokuwiki
10if (!defined('DOKU_INC')) {
11    die();
12}
13
14if (!defined('DOKU_PLUGIN')) {
15    define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
16}
17require_once(DOKU_PLUGIN.'syntax.php');
18
19/**
20 * All DokuWiki plugins to extend the parser/rendering mechanism
21 * need to inherit from this class
22 */
23class syntax_plugin_dokucrypt2 extends DokuWiki_Syntax_Plugin
24{
25    public $curNum=0;
26    public $curLock=0;
27    /**
28     * return some info
29     */
30    public function getInfo()
31    {
32        return array(
33            'author' => 'Scott Moser, Maintainer Sherri Wheeler',
34            'email'  => 'Twitter @SyntaxSeed or http://SyntaxSeed.com',
35            'date'   => '2022-02-02',
36            'name'   => 'Client Side Encryption Plugin',
37            'desc'   => 'Client side cryptography enabling encrypting blocks of text within a wiki page.',
38            'url'    => 'https://www.dokuwiki.org/plugin:dokucrypt2',
39        );
40    }
41
42    public function getType()
43    {
44        return 'protected';
45    }
46    public function getAllowedTypes()
47    {
48        return array();
49    }
50    public function getSort()
51    {
52        return 999;
53    }
54    public function connectTo($mode)
55    {
56        $this->Lexer->addEntryPattern(
57            '<ENCRYPTED.*?>(?=.*?</ENCRYPTED>)',
58            $mode,
59            'plugin_dokucrypt2'
60        );
61    }
62    public function postConnect()
63    {
64        $this->Lexer->addExitPattern('</ENCRYPTED>', 'plugin_dokucrypt2');
65    }
66
67    /**
68     * Handle the match
69     */
70    public function handle($match, $state, $pos, Doku_Handler $handler)
71    {
72        switch ($state) {
73          case DOKU_LEXER_ENTER:
74                // parse something like <ENCRYPTED> or <ENCRYPTED LOCK=foo>
75                $attr=array( "lock" => "default", "collapsed" => "1" );
76                if (($x=strpos($match, "LOCK="))!==false) {
77                    $x+=strlen("LOCK=");
78                    if (($end=strpos($match, " ", $x))!==false) {
79                        $len=$end-$x;
80                    } else {
81                        $len=-1;
82                    }
83                    $attr["lock"]=substr($match, $x, $len);
84                }
85                if (($x=strpos($match, "COLLAPSED="))!==false) {
86                    $x+=strlen("COLLAPSED=");
87                    if (($end=strpos($match, " ", $x))!==false) {
88                        $len=$end-$x;
89                    } else {
90                        $len=-1;
91                    }
92                    $attr["collapsed"]=substr($match, $x, $len);
93                }
94                return(array($state,$attr));
95          case DOKU_LEXER_UNMATCHED:  return array($state, $match);
96          case DOKU_LEXER_EXIT:       return array($state, '');
97        }
98        return array();
99    }
100
101    /**
102     * Create output
103     */
104    public function render($mode, Doku_Renderer $renderer, $data)
105    {
106        if ($mode == 'xhtml') {
107            list($state, $match) = $data;
108            switch ($state) {
109              case DOKU_LEXER_ENTER:
110                $this->curLock=$match;
111                break;
112              case DOKU_LEXER_UNMATCHED:
113                $curid = "crypto_decrypted_" . $this->curNum;
114
115                $renderer->doc.="<a id='$curid" . "_atag' " .
116                  "class='wikilink1 dokucrypt2dec JSnocheck' " .
117                  "href=\"javascript:toggleCryptDiv(" .
118                  "'$curid','" . $this->curLock["lock"] . "','" .
119                  htmlspecialchars(str_replace("\n", "\\n", $match)) . "');\">" .
120                  "Decrypt Encrypted Text</a>" .
121                  "&nbsp;&nbsp;[<a class='wikilink1 dokucrypt2toggle JSnocheck' " .
122                  "href=\"javascript:toggleElemVisibility('$curid');\">" .
123                  "Toggle Visible</a>]\n" .
124                  "<PRE id='$curid' class='dokucrypt2pre' style=\"" .
125                     (($this->curLock["collapsed"] == 1) ?
126                        "visibility:hidden;position:absolute;white-space:pre-wrap;word-wrap: break-word;" :
127                        "visibility:visible;position:relative;white-space:pre-wrap;word-wrap: break-word;") .
128                  "\">". htmlspecialchars($match)."</PRE>";
129                $this->curNum++;
130                break;
131              case DOKU_LEXER_EXIT:
132                break;
133            }
134            return true;
135        }
136        return false;
137    }
138}
139