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/');
29
30/**
31 * All DokuWiki plugins to extend the parser/rendering mechanism
32 * need to inherit from this class
33 */
34class syntax_plugin_stars2 extends DokuWiki_Syntax_Plugin {
35
36    /**
37     * return some info
38     */
39    function getInfo(){
40        return array(
41            'author' => 'Zahno Silvan',
42            'email'  => 'zaswiki@gmail.com',
43            'date'   => '2025-02-07',
44            'name'   => 'Stars2 Plugin',
45            'desc'   => 'Embedding Rating Stars',
46            'url'    => 'https://github.com/tschinz/dokuwiki_stars_plugin',
47        );
48    }
49
50    /**
51     * What kind of syntax are we?
52     */
53    function getType(){
54        return 'substition';
55    }
56
57    /**
58     * Where to sort in?
59     */
60    function getSort(){
61        return 299;
62    }
63
64    /**
65     * Connect pattern to lexer
66     */
67    function connectTo($mode) {
68        $this->Lexer->addSpecialPattern('\{\{stars>.*?\}\}',$mode,'plugin_stars2');
69    }
70
71    /**
72     * Handle the match
73     */
74    function handle($match, $state, $pos, Doku_Handler $handler){
75        switch ($state) {
76          case DOKU_LEXER_ENTER :
77            break;
78          case DOKU_LEXER_MATCHED :
79            break;
80          case DOKU_LEXER_UNMATCHED :
81            break;
82          case DOKU_LEXER_EXIT :
83            break;
84          case DOKU_LEXER_SPECIAL :
85            return $match;
86            break;
87        }
88        return array();
89    }
90
91    /**
92     * Create output
93     */
94    function render($mode, Doku_Renderer $renderer, $data) {
95        if($mode == 'xhtml' || $mode == 'odt')
96        {
97            // strip {{stars> from start
98            $data = substr($data,8);
99            // strip }} from end
100            $data = substr($data,0,-2);
101            $num = $data;
102
103            if (empty($num))
104                $num = "0/5";
105            $empty = true;
106
107            // Get seperate num's
108            $num=explode('/',$num); // Strip size
109            if (!isset($num[1]))
110                $num[1] = $num[0];
111
112            if ($num[0]>$num[1])
113                $num[1]=$num[0];
114
115            if ($num[1]>10)
116            {
117                $num[0] = 10 * $num[0] / $num[1];
118                $num[1] = 10;
119            } // end if ($num[1]>10)
120            if ($mode == 'xhtml')
121            {
122                if ($empty == true)
123                    $renderer->doc .= $this->_Stars_static($num);
124                else
125                    $renderer->doc .= $this->_Stars_dynamic($num);
126            }
127            else
128            {
129                $this->_Stars_static_for_odt($renderer, $num);
130            }
131
132            return true;
133        }
134        return false;
135    }
136
137    function _Stars_static($d)
138    {
139        # Get the config options
140        $options['height']       = $this->getConf('height');
141
142        $string='<span class="starspan" onload="loadStars()" alt="' . $d[0] . '/' . $d[1] . ' stars">';
143
144        // Not rated yet images
145        if($d[0] < 0)
146        {
147            $d[0] = -$d[0];
148            $nry = true;
149        }
150        else
151            $nry = false;
152
153        // render full stars
154        for($i=1; $i<=$d[0]; $i++)
155            if($nry == true)
156                $string .= '<img class="fullstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'unknownstar.png"/>';
157            else
158                $string .= '<img class="fullstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'fullstar.png"/>';
159
160        // render half star if necessary
161        if($i-.5 <= $d[0])
162        {
163            $string .= '<img class="halfstarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'halfstar.png"/>';
164            $i+= .5;
165        } // end if($i-$d[0] > 0)
166
167        for($i;$i<=$d[1];$i++)
168            $string .= '<img class="emptystarimage" id="'.$i.'" style="height:'.$options['height'].'px;" src="' . DOKU_PLUGIN_STARS2_IMAGES . 'emptystar.png"/>';
169
170        $string .= '</span>';
171
172        return $string;
173    } // end function _Stars_static($d)
174
175    function _Stars_dynamic($d)
176    {
177        # Get the config options
178        $options['height']       = $this->getConf('height');
179
180        $string='<span class="starspan" onload="loadStars()" alt="' . $d[0] . '/' . $d[1] . ' stars">';
181
182        // render full stars
183        for($i=1; $i<=$d[0]; $i++)
184            $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"/>';
185
186        // render half star if necessary
187        if($i-.5 <= $d[0])
188        {
189            $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"/>';
190            $i+= .5;
191        } // end if($i-$d[0] > 0)
192
193        for($i;$i<=$d[1];$i++)
194            $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"/>';
195
196        $string .= '</span>';
197
198        return $string;
199    } // end function _Stars_dynamic($d)
200
201    function _Stars_static_for_odt(&$renderer, $d)
202    {
203        // Prepare the full path for the function _odtAddImage
204        // otherwise the file will not be found!
205        $src_unknown = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'unknownstar.png';
206        $src_full    = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'fullstar.png';
207        $src_half    = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'halfstar.png';
208        $src_empty   = DOKU_INC . DOKU_PLUGIN_STARS2_IMAGES . 'emptystar.png';
209
210        // Not rated yet images
211        if($d[0] < 0)
212        {
213            $d[0] = -$d[0];
214            $nry = true;
215        }
216        else
217            $nry = false;
218
219        // render full stars
220        for($i=1; $i<=$d[0]; $i++)
221        {
222            if($nry == true)
223            {
224                $renderer->_odtAddImage($src_unknown);
225            }
226            else
227            {
228                $renderer->_odtAddImage($src_full);
229            }
230        }
231
232        // render half star if necessary
233        if($i-.5 <= $d[0])
234        {
235            $renderer->_odtAddImage($src_half);
236            $i+= .5;
237        } // end if($i-$d[0] > 0)
238
239        for($i;$i<=$d[1];$i++)
240        {
241            $renderer->_odtAddImage($src_empty);
242        }
243    } // end function _Stars_static_for_odt($d)
244
245}
246
247