1<?php
2// must be run within Dokuwiki
3if(!defined('DOKU_INC')) die();
4
5/**
6 * DokuWiki Plugin dlcounter (Syntax Component)
7 *
8 * @author Phil Ide <phil@pbih.eu>
9 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
10 */
11
12class syntax_plugin_dlcounter extends DokuWiki_Syntax_Plugin {
13
14    /**
15     * What kind of syntax are we?
16     */
17    function getType() {
18        return 'substition';
19    }
20
21    /**
22     * What about paragraphs?
23     */
24    function getPType() {
25        return 'normal';
26    }
27
28    /**
29     * Where to sort in?
30     */
31    function getSort() {
32        return 155;
33    }
34
35    /**
36     * Connect pattern to lexer
37     */
38    function connectTo($mode) {
39        $this->Lexer->addSpecialPattern('\{\{dlcounter>[^\}]+\}\}', $mode, 'plugin_dlcounter');
40    }
41
42    /**
43     * Handle the match
44     */
45    function handle($match, $state, $pos, Doku_Handler $handler) {
46        if (isset($_REQUEST['comment'])) {
47            return false;
48        }
49        $command = trim(substr($match, 12 ,-2));
50        $x = explode('?', $command);
51        $command = $x[0];
52        $params = explode(' ', $x[1]);
53
54        $data = array(
55                    'command' => $command,
56                    'file'    => '',
57                    'sort'    => 'none',
58                    'strip'   => false,
59                    'align'   => 'right',
60                    'minwidth' => 0,
61                    'cpad'    => 1,
62                    'halign'  => 'center',
63                    'bold'    => 'b',
64                    'header'  => true,
65                    'htext'   => 'Downloads'
66                );
67
68        foreach( $params as $item ){
69            // switch turns out to be buggy for multiple iterations - grrrrr!
70            if( $item == 'sort' )          $data['sort'] = $item;
71            else if( $item == 'rsort' )    $data['sort'] = $item;
72            else if( $item == 'strip' )    $data['strip'] = true;
73            else if( $item == 'left' )     $data['align'] = $item;
74            else if( $item == 'center' )   $data['align'] = $item;
75            else if( $item == 'right' )    $data['align'] = $item;
76            else if( $item == 'hleft' )    $data['halign'] = 'left';
77            else if( $item == 'hcenter' )  $data['halign'] = 'center';
78            else if( $item == 'hright' )   $data['halign'] = 'right';
79            else if( $item == 'nobold' )   $data['bold'] = 'nobold';
80            else if( $item == 'noheader' ) $data['header'] = false;
81            else if( substr( $item, 0, 6) == 'htext=' ){
82                $data['htext'] = explode('"', $x[1])[1];
83            }
84            else if( substr( $item, 0, 9) == 'minwidth=' ){
85                $data['minwidth'] = explode('=', $item)[1];
86            }
87            else if( substr( $item, 0, 5) == 'cpad=' ){
88                $data['cpad'] = explode('=', $item)[1];
89            }
90            else $data['file'] = $item;
91        }
92        return $data;
93    }
94
95
96    /**
97     * Create output
98     */
99    function render($format, Doku_Renderer $renderer, $data) {
100        $fname = DOKU_INC.'data/counts/download_counts.json';
101        $json = json_decode( file_get_contents($fname), TRUE );
102
103        $command = $data['command'];
104        $file = $data['file'];
105
106        //$renderer->doc .= "<pre>".print_r($data, true)."</pre>"; // for debugging
107
108        if( $command == 'file' ){
109            // just want a counter
110            $count = 0;
111            if( $file != "" && array_key_exists( $file, $json ) ){
112                $count = $json[$file];
113                $renderer->doc .= $count;
114            }
115        }
116        else {
117            // dump all the data in a table
118            $sort = $data['sort'] == '' ? 'sort' : $data['sort'];
119
120            if( $command == 'name' ){
121                $json = $this->dlcounter_switchKeys($json, true);
122
123                if( $sort == 'sort' ) ksort($json);
124                else if( $sort == 'rsort' ) krsort($json);
125
126                $json = $this->dlcounter_switchKeys($json, false);
127            }
128            else if( $command == 'count' ){
129                if( $sort == 'sort' ) asort( $json );
130                else if( $sort == 'rsort' ) arsort( $json );
131            }
132
133            $table = "<table>";
134            if( $data['header'] ){
135                $table .= "<tr><th colspan=2 style='text-align:".$data['halign'].";'>".$data['htext']."</th></tr>";
136            }
137            foreach( $json as $file => $count ){
138                $fdata = explode(':', $file);
139                $c = count($fdata);
140                $fdata[$c-1] = "<".$data['bold'].">".$fdata[$c-1]."</".$data['bold'].">";
141                if( $data['strip'] ) $file = $fdata[$c-1];
142                else $file = implode(':', $fdata);
143                $table .= "<tr><td style='text-align:".$data['align'].";'>$file</td>".
144                            "<td align=right style='text-align: right;min-width: ".$data['minwidth']."em;padding-left: ".$data['cpad']."em;'>$count</td></tr>";
145            }
146            $table .= "</table>";
147            $renderer->doc .= $table;
148        }
149        return true;
150    }
151
152
153    function dlcounter_switchKeys( $arr, $back2Front ){
154        $keys = array_keys( $arr );
155        for( $i = 0; $i < count($keys); $i++ ){
156            if( $back2Front ) $keys[$i] = $this->switchKeyHelperA( $keys[$i] );
157            else $keys[$i] = $this->switchKeyHelperB( $keys[$i] );
158        }
159        return array_combine( $keys, $arr );
160    }
161
162    // move the fileame to the front of the path
163    function switchKeyHelperA( $v ){
164        $a = explode(':', $v);
165        $f = array_pop($a);
166        array_unshift( $a, $f );
167        return implode(':', $a );
168    }
169
170    // move the filename from the front of the path to the end
171    function switchKeyHelperB( $v ){
172        $a = explode(':', $v);
173        $f = array_shift($a);
174        array_push( $a, $f );
175        return implode(':', $a );
176    }
177
178}
179