1<?php
2/*
3 * DokuWiki stars plugin
4 * 2018 Zahno Silvan
5 * Usage:
6 *
7 * {{stars>num}}         -- num = 5 or 5/7 or 100/1000
8 *                       -- num = -1 gives a "not rated yet"
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the LGNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * LGNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the LGNU Lesser General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23 */
24
25
26if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
27if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
28if(!defined('DOKU_PLUGIN_STARS2_IMAGES')) define('DOKU_PLUGIN_STARS2_IMAGES',DOKU_BASE.'lib/plugins/stars2/images/');
29require_once(DOKU_PLUGIN.'syntax.php');
30
31/**
32 * All DokuWiki plugins to extend the parser/rendering mechanism
33 * need to inherit from this class
34 */
35class syntax_plugin_stars2 extends DokuWiki_Syntax_Plugin {
36
37    /**
38     * return some info
39     */
40    function getInfo(){
41        return array(
42            'author' => 'Zahno Silvan',
43            'email'  => 'zaswiki@gmail.com',
44            'date'   => '2020-07-07',
45            'name'   => 'Stars2 Plugin',
46            'desc'   => 'Embedding Rating Stars',
47            'url'    => 'https://github.com/tschinz/dokuwiki_stars_plugin',
48        );
49    }
50
51    /**
52     * What kind of syntax are we?
53     */
54    function getType(){
55        return 'substition';
56    }
57
58    /**
59     * Where to sort in?
60     */
61    function getSort(){
62        return 299;
63    }
64
65    /**
66     * Connect pattern to lexer
67     */
68    function connectTo($mode) {
69        $this->Lexer->addSpecialPattern('\{\{stars>.*?\}\}',$mode,'plugin_stars2');
70    }
71
72    /**
73     * Handle the match
74     */
75    function handle($match, $state, $pos, Doku_Handler $handler){
76        switch ($state) {
77          case DOKU_LEXER_ENTER :
78            break;
79          case DOKU_LEXER_MATCHED :
80            break;
81          case DOKU_LEXER_UNMATCHED :
82            break;
83          case DOKU_LEXER_EXIT :
84            break;
85          case DOKU_LEXER_SPECIAL :
86            return $match;
87            break;
88        }
89        return array();
90    }
91
92    /**
93     * Create output
94     */
95    function render($mode, Doku_Renderer $renderer, $data) {
96        if($mode == 'xhtml' || $mode == 'odt')
97        {
98            // strip {{stars> from start
99            $data = substr($data,8);
100            // strip }} from end
101            $data = substr($data,0,-2);
102            $num = $data;
103
104            if (empty($num))
105                $num = "0/5";
106            $empty = true;
107
108            // Get seperate num's
109            $num=explode('/',$num); // Strip size
110            if (!isset($num[1]))
111                $num[1] = $num[0];
112
113            if ($num[0]>$num[1])
114                $num[1]=$num[0];
115
116            if ($num[1]>10)
117            {
118                $num[0] = 10 * $num[0] / $num[1];
119                $num[1] = 10;
120            } // end if ($num[1]>10)
121            if ($mode == 'xhtml')
122            {
123                if ($empty == true)
124                    $renderer->doc .= $this->_Stars_static($num);
125                else
126                    $renderer->doc .= $this->_Stars_dynamic($num);
127            }
128            else
129            {
130                $this->_Stars_static_for_odt($renderer, $num);
131            }
132
133            return true;
134        }
135        return false;
136    }
137
138    function _Stars_static($d)
139    {
140        # Get the config options
141        $options['height']       = $this->getConf('height');
142
143        $string='<span class="starspan" onload="loadStars()" alt="' . $d[0] . '/' . $d[1] . ' stars">';
144
145        // Not rated yet images
146        if($d[0] < 0)
147        {
148            $d[0] = -$d[0];
149            $nry = true;
150        }
151        else
152            $nry = false;
153
154        // render full stars
155        for($i=1; $i<=$d[0]; $i++)
156            if($nry == true)
157                $string .= '<img class="fullstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'unknownstar.png"/>';
158            else
159                $string .= '<img class="fullstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'fullstar.png"/>';
160
161        // render half star if necessary
162        if($i-.5 <= $d[0])
163        {
164            $string .= '<img class="halfstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'halfstar.png"/>';
165            $i+= .5;
166        } // end if($i-$d[0] > 0)
167
168        for($i;$i<=$d[1];$i++)
169            $string .= '<img class="emptystarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'emptystar.png"/>';
170
171        $string .= '</span>';
172
173        return $string;
174    } // end function _Stars_static($d)
175
176    function _Stars_dynamic($d)
177    {
178        # Get the config options
179        $options['height']       = $this->getConf('height');
180
181        $string='<span class="starspan" onload="loadStars()" alt="' . $d[0] . '/' . $d[1] . ' stars">';
182
183        // render full stars
184        for($i=1; $i<=$d[0]; $i++)
185            $string .= '<img class="fullstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" onmouseover="highlight(this.id)" onclick="setStar(this.id)" onmouseout="losehighlight(this.id)" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'fullstar.png"/>';
186
187        // render half star if necessary
188        if($i-.5 <= $d[0])
189        {
190            $string .= '<img class="halfstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" onmouseover="highlight(this.id)" onclick="setStar(this.id)" onmouseout="losehighlight(this.id)" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'halfstar.png"/>';
191            $i+= .5;
192        } // end if($i-$d[0] > 0)
193
194        for($i;$i<=$d[1];$i++)
195            $string .= '<img class="emptystarimage" id="'.$i.'" style="height:'.$options['height'].'px;" onmouseover="highlight(this.id)" onclick="setStar(this.id)" onmouseout="losehighlight(this.id)" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'emptystar.png"/>';
196
197        $string .= '</span>';
198
199        return $string;
200    } // end function _Stars_dynamic($d)
201
202    function _Stars_static_for_odt(&$renderer, $d)
203    {
204        // Prepare the full path for the function _odtAddImage
205        // otherwise the file will not be found!
206        $src_unknown = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'unknownstar.png';
207        $src_full    = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'fullstar.png';
208        $src_half    = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'halfstar.png';
209        $src_empty   = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'emptystar.png';
210
211        // Not rated yet images
212        if($d[0] < 0)
213        {
214            $d[0] = -$d[0];
215            $nry = true;
216        }
217        else
218            $nry = false;
219
220        // render full stars
221        for($i=1; $i<=$d[0]; $i++)
222        {
223            if($nry == true)
224            {
225                $renderer->_odtAddImage($src_unknown);
226            }
227            else
228            {
229                $renderer->_odtAddImage($src_full);
230            }
231        }
232
233        // render half star if necessary
234        if($i-.5 <= $d[0])
235        {
236            $renderer->_odtAddImage($src_half);
237            $i+= .5;
238        } // end if($i-$d[0] > 0)
239
240        for($i;$i<=$d[1];$i++)
241        {
242            $renderer->_odtAddImage($src_empty);
243        }
244    } // end function _Stars_static_for_odt($d)
245
246}
247
248