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