1<?php
2/**
3* Plugin QuizLib: Implements quizes for self test on user side per JavaScript.
4*
5* @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6* @author     Enrico Billich <enrico.billich@etit.tu-chemnitz.de
7*/
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
13
14/**
15 * All DokuWiki plugins to extend the parser/rendering mechanism
16 * need to inherit from this class
17 */
18class syntax_plugin_quizlib extends DokuWiki_Syntax_Plugin {
19
20	protected $pattern_start  = '<quizlib\b.*?>(?=.*?</quizlib>)';
21    protected $pattern_end    = '</quizlib>';
22    protected $quizattributes = array();
23
24    public function getType(){ return 'container'; }
25    public function getAllowedTypes() {return array();} //array('formatting', 'substition', 'disabled')
26    public function getPType(){return 'block';}
27    public function getSort(){ return 158; }
28
29    public function connectTo($mode) {
30        $this->Lexer->addEntryPattern($this->pattern_start, $mode, 'plugin_quizlib');
31    }
32
33    public function postConnect() {
34        $this->Lexer->addExitPattern($this->pattern_end, 'plugin_quizlib');
35        //$this->Lexer->addPattern($this->header_pattern, 'plugin_quizlib');
36    }
37
38
39    /**
40     * Handle the match
41     */
42    public function handle($match, $state, $pos, Doku_Handler $handler){
43        switch ($state) {
44            case DOKU_LEXER_ENTER :
45                $attributes = array();
46                $xml        = simplexml_load_string(str_replace('>', '/>', $match));
47
48                foreach ($xml->attributes() as $key => $value) {
49                    $attributes[$key] = (string) $value;
50                }
51
52                $this->quizattributes = $attributes; // saved for DOKU_LEXER_EXIT
53                return array($state, $attributes);
54
55            case DOKU_LEXER_UNMATCHED :
56                return array($state, $match);
57
58            case DOKU_LEXER_EXIT :
59                return array($state, $this->quizattributes);
60        }
61        return array();
62    }
63
64    /**
65     * Create output
66     */
67    public function render($mode, Doku_Renderer $renderer, $data) {
68        // $data is what the function handle() return'ed.
69        if($mode == 'xhtml'){
70            /** @var Doku_Renderer_xhtml $renderer */
71            list($state,$match) = $data;
72            switch ($state) {
73                case DOKU_LEXER_ENTER :
74                    if(!isset($match['id'])) return false;
75                    $renderer->doc .= sprintf('<div id="%s">', $match['id']) . PHP_EOL;
76                    break;
77
78                case DOKU_LEXER_UNMATCHED :
79                    $xml = @simplexml_load_string('<root>' . $match . '</root>');
80                    if (false === $xml) {
81                        $renderer->doc .= 'Failed parsing quizlib-XML' . PHP_EOL;
82                    }
83                    else {
84                        $questioncount = 0;
85                        foreach ($xml->children() as $question){
86                            $renderer->doc .= '<div class="quizlib-card quizlib-question">' . PHP_EOL;
87                            foreach ($question->attributes() as $attribute=>$attributevalue){
88                                switch ($attribute) {
89                                    case 'title' :
90                                        $renderer->doc .= '<div class="quizlib-question-title">' . $attributevalue . '</div>' . PHP_EOL;
91                                        break;
92                                    case 'type' :
93                                        switch ($attributevalue) {
94                                            case 'text' :
95                                                $renderer->doc .= '<div class="quizlib-question-answers"><input type="text" name="q'.$questioncount.'"></div>' . PHP_EOL;
96                                                break;
97                                            case 'radio' :
98                                                $renderer->doc .= '<div class="quizlib-question-answers"><ul>' . PHP_EOL;
99                                                $answers = explode('|', $question);
100                                                $answercount = 0;
101                                                foreach ($answers as $answer){
102                                                    $renderer->doc .= '<li><label><input type="radio" name="q'.$questioncount.'" value="a'.$answercount.'">'.$answer.'</label></li>' . PHP_EOL;
103                                                    $answercount++;
104                                                }
105                                                $renderer->doc .= '</ul></div>' . PHP_EOL;
106                                                break;
107                                            case 'checkbox' :
108                                                $renderer->doc .= '<div class="quizlib-question-answers"><ul>' . PHP_EOL;
109                                                $answers = explode('|', $question);
110                                                $answercount = 0;
111                                                foreach ($answers as $answer){
112                                                    $renderer->doc .= '<li><label><input type="checkbox" name="q'.$questioncount.'" value="a'.$answercount.'">'.$answer.'</label></li>' . PHP_EOL;
113                                                    $answercount++;
114                                                }
115                                                $renderer->doc .= '</ul></div>' . PHP_EOL;
116                                                break;
117                                        }
118                                        break;
119                                }
120                            }
121                            $renderer->doc .= '</div>' . PHP_EOL;
122                            $questioncount++;
123                        }
124                    }
125                    break;
126                case DOKU_LEXER_EXIT :
127                    if(!isset($match['id']) or !isset($match['rightanswers']) or !isset($match['submit'])) return false;
128                    $renderer->doc .= sprintf('<button class="quizlib-submit" type="button" onclick="quizlibShowResults(\'%s\',%s);">%s</button>',$match['id'],$match['rightanswers'],$match['submit']) . PHP_EOL;
129                    $renderer->doc .= '</div>' . PHP_EOL;
130                    $renderer->doc .= '<div id="quizlib-result" class="quizlib-card">' . PHP_EOL;
131                    $renderer->doc .= 'You Scored <span id="quiz-percent"></span>% - <span id="quiz-score"></span>/<span id="quiz-max-score"></span><br/>' . PHP_EOL;
132                    $renderer->doc .= '</div>' . PHP_EOL;
133                    break;
134            }
135            return true;
136        }
137        return false;
138    }
139
140}
141?>
142