xref: /plugin/sortablejs/syntax.php (revision 274578ffeea535787fddcf6d57c322b9b3890c7d)
1<?php
2/**
3 * Sortablejs: Javascript for Sortable table
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Otto Vainio
7 * version 1.1 Fixed javascript error in sorttable js
8 * version 2.0 Added <div> to sort any table
9 * version 2.1 Changed script to allow multiple sortable tables in one page
10 * version 2.2 A table can now be sorted by one column by default.
11 * version 2.2a css+js compress broke this script. Now fixed some jslint complains.
12 * version 2.3 Added support for odt plugin. (Aurélien Bompard)
13 * version 2.3a Fixed default sort with aligned text (Andre Rauschenbach)
14 * version 2.4 Added options to set manual override options for column sort. (nosort, numeric, alpha, ddmm, mmdd)
15 * version 2.5 Fixed problems with secionediting, footnotes and edittable
16 * version 2.6 Added support for jQuery and dokuwiki Weatherwax ->
17 * version 2.7 Fixed problem with first row not getting sorted
18 * version 2.8 Fixed problem with first row not getting sorted in default sort. Added option "sumrow" to prevent sum line sort.
19 * version 2.9 fixed problem with header row being sorted in earlier versions of dokuwiki.
20 * version 2.10 fixed odt export (LarsGit223)
21 * version 2.11 Added ip address sort. Thanks Chefkeks
22 * version 2.12 php 7 compatibility. Cahnged split -> explode
23 * @author     Vaxquis
24 * version 2.13 implemented https://github.com/oiv/sortablejs/pull/18/files for PHP 7 compatibility, minor style/pretty print changes
25 */
26// must be run within Dokuwiki
27if ( !defined( 'DOKU_INC' ) )
28    die();
29if ( !defined( 'DOKU_PLUGIN' ) )
30    define( 'DOKU_PLUGIN', DOKU_INC.'lib/plugins/' );
31require_once(DOKU_PLUGIN.'syntax.php');
32//
33class syntax_plugin_sortablejs extends DokuWiki_Syntax_Plugin {
34
35    function getType() {
36        return 'container';
37    }
38
39    function getPType() {
40        return 'block';
41    }
42
43    function getSort() {
44        return 371;
45    }
46
47    function getAllowedTypes() {
48        return array( 'container', 'formatting', 'substition' );
49    }
50
51    function connectTo( $mode ) {
52        $this->Lexer->addEntryPattern( '<sortable[^>]*>(?=.*?</sortable>)', $mode, 'plugin_sortablejs' );
53//    $this->Lexer->addEntryPattern('\x3Csortable.*?\x3E',$mode,'plugin_sortablejs');
54//    $this->Lexer->addEntryPattern('<sortable>',$mode,'plugin_sortablejs');
55    }
56
57    function postConnect() {
58        $this->Lexer->addExitPattern( '</sortable>', 'plugin_sortablejs' );
59    }
60
61    function handle( $match, $state, $pos, Doku_Handler $handler ) {
62
63        switch ( $state ) {
64            case DOKU_LEXER_ENTER :
65                $match = substr( $match, 9, -1 );
66                $match = trim( $match );
67                $scl = "";
68                if ( strlen( $match ) > 0 ) {
69                    $scl = $this->__validateOptions( $match );
70                }
71                return array( $state, $scl );
72            case DOKU_LEXER_UNMATCHED :
73//        return p_render('xhtml',p_get_instructions($match),$info);
74                return array( $state, $match );
75            case DOKU_LEXER_EXIT :
76//        return "</div>";
77                return array( $state, "" );
78        }
79        return array();
80    }
81
82    function render( $mode, Doku_Renderer $renderer, $data ) {
83        list($state, $match) = $data;
84        if ( $mode == 'xhtml' ) {
85            switch ( $state ) {
86                case DOKU_LEXER_ENTER :
87                    $renderer->doc .= "<div class=\"sortable$match\">";
88                    break;
89                case DOKU_LEXER_UNMATCHED :
90//          $dbgr = p_render('xhtml',p_get_instructions($match),$info);
91//          $renderer->doc .= p_render('xhtml',p_get_instructions($match),$info);
92//          $renderer->doc .= $match;
93//          $instructions = array_slice(p_get_instructions($match), 1, -1);
94                    $instructions = p_get_instructions( $match );
95                    foreach( $instructions as $instruction ) {
96                        call_user_func_array( array( &$renderer, $instruction[0] ), $instruction[1] );
97                    }
98
99                    break;
100                case DOKU_LEXER_EXIT :
101                    $renderer->doc .= "</div>";
102                    break;
103            }
104            return true;
105        } else if ( $mode == 'odt' ) {
106            switch ( $state ) {
107                case DOKU_LEXER_ENTER :
108                    // In ODT, tables must not be inside a paragraph. Make sure we
109                    // closed any opened paragraph
110                    $renderer->p_close();
111                    break;
112                case DOKU_LEXER_UNMATCHED :
113                    $instructions = array_slice( p_get_instructions( $match ), 1, -1 );
114                    foreach( $instructions as $instruction ) {
115                        call_user_func_array( array( &$renderer, $instruction[0] ), $instruction[1] );
116                    }
117                    break;
118                case DOKU_LEXER_EXIT :
119                    //$renderer->p_open();
120                    // DO NOT re-open the paragraph, it would cause an error if the table is the last content on a page
121                    break;
122            }
123            return true;
124        }
125        return false;
126    }
127
128    function __validateOptions( $opts ) {
129        $oa = explode( " ", $opts );
130        $ret = "";
131        foreach( $oa as $opt ) {
132            list($c, $v) = explode( "=", $opt );
133            if ( $c == "sumrow" ) {
134                $c = $v;
135                $v = "sumrow";
136                if ( $c == "" ) {
137                    $c = "1";
138                }
139            } else if ( $c == "3phase" ) {
140                $v = $c;
141                $c = "";
142            }
143            if ( $v != null ) {
144                $cmpr = $v;
145            } else {
146                if ( preg_match( '/r?\d*/', $c, $matches ) ) {
147                    $cmpr = 'sort';
148                }
149            }
150            switch ( $cmpr ) {
151                case '3phase':
152                    $ret .= " threephase";
153                    break;
154                case 'nosort':
155                    $ret .= " col_".$c."_nosort";
156                    break;
157                case 'numeric':
158                    $ret .= " col_".$c."_numeric";
159                    break;
160                case 'ddmm':
161                    $ret .= " col_".$c."_ddmm";
162                    break;
163                case 'mmdd':
164                    $ret .= " col_".$c."_mmdd";
165                    break;
166                case 'alpha':
167                case 'text':
168                    $ret .= " col_".$c."_alpha";
169                    break;
170                case 'sort':
171                    $ret .= ' sort'.$opt;
172                    break;
173                case 'sumrow':
174                    $ret .= ' sortbottom_'.$c;
175                    //$ret = ' sortbottom' . $ret;
176                    break;
177            }
178        }
179        return $ret;
180    }
181}
182