1<?php 2 3// must be run within Dokuwiki 4if ( !defined( 'DOKU_INC' ) ) die(); 5 6if ( !defined( 'DOKU_PLUGIN' ) ) define( 'DOKU_PLUGIN', DOKU_INC . 'lib/plugins/' ); 7 8require_once( DOKU_PLUGIN . 'action.php' ); 9 10class action_plugin_tagentry extends DokuWiki_Action_Plugin { 11 12 /** 13 * register the eventhandlers 14 */ 15 public function register(Doku_Event_Handler $controller) { 16 // hook 17 $controller->register_hook( 18 'HTML_EDITFORM_OUTPUT', 'BEFORE', $this, 19 'handle_editform_output' 20 ); 21 } 22 23 /** 24 * Create the additional fields for the edit form. 25 */ 26 function handle_editform_output( &$event, $param ) { 27 $pos = $event->data->findElementByAttribute( 'type', 'submit' ); 28 if ( !$pos ){ return; } 29 $prefixHidden = empty( $event->data->_hidden['prefix'] ); 30 $suffixHidden = empty( $event->data->_hidden['suffix'] ); 31 if ( $prefixHidden || ! $suffixHidden ){ 32 return; 33 } 34 // get all tags 35 $tagns = $this->getConf( 'namespace' ); 36 if ( $thlp =& plugin_load( 'helper', 'tag' ) ) { 37 if ( $this->getConf( 'tagsrc' ) == 'Pagenames in tag NS' ) { 38 $tagnst = $thlp->getConf( 'namespace' ); 39 if ( !empty( $tagnst ) ) 40 $tagns = $tagnst; 41 } 42 } 43 if ( $this->getConf( 'tagsrc' ) == 'All tags' && $thlp ) { 44 $alltags = array_map( 'trim', idx_getIndex( 'subject', '_w' ) ); 45 } else { 46 $alltags = $this->_getpages( $tagns ); 47 } 48 49 // get already assigned tags for this page 50 $assigned = false; 51 if ( 1 ) { // parse wiki-text to pick up tags for draft/prevew 52 $wikipage = ''; 53 $wt = $event->data->findElementByType( 'wikitext' ); 54 if ( $wt !== false ) { 55 $wikipage = $event->data->_content[$wt]['_text']; 56 } 57 if ( !empty( $wikipage ) ){ 58 if ( preg_match( '@\{\{tag>(.*?)\}\}@', $wikipage, $m ) ) { 59 $assigned = explode( ' ', $m[1] ); 60 } 61 } 62 } 63 if ( !is_array( $assigned ) ) { 64 // those are from the prev. saved version. 65 global $ID; 66 $meta = array(); 67 $meta = p_get_metadata( $ID ); 68 $assigned = $meta['subject']; 69 } 70 $options = array( 71 'blacklist' => explode( ' ', $this->getConf( 'blacklist' ) ), 72 'assigned' => $assigned, 73 ); 74 $out = '<div id="plugin__tagentry_wrapper">'; 75 $out .= $this->_format_tags( $alltags, $options ); 76 $out .= '</div>'; 77 $event->data->insertElement( $pos++, $out ); 78 } 79 80 /** 81 * callback function for dokuwiki search() 82 * 83 * Build a list of tags from the tag namespace 84 * $opts['ns'] is the namespace to browse 85 */ 86 function _tagentry_search_tagpages( &$data, $base, $file, $type, $lvl, $opts ) { 87 $return = true; 88 $item = array(); 89 if ( $type == 'd' ) { 90 // TODO: check if namespace mismatch -> break recursion early. 91 return true; 92 } elseif ( $type == 'f' && !preg_match( '#\.txt$#', $file ) ) { 93 return false; 94 } 95 $id = pathID( $file ); 96 if ( getNS( $id ) != $opts['ns'] ) 97 return false; 98 if ( isHiddenPage( $id ) ) { 99 return false; 100 } 101 if ( $type == 'f' && auth_quickaclcheck( $id ) < AUTH_READ ) { 102 return false; 103 } 104 $data[] = noNS( $id ); 105 return $return; 106 } 107 108 /** 109 * list all tags from the topic index. 110 * (requires newer version of the tag plugin) 111 * 112 * @param $thlp pointer to tag plugin's helper 113 * @return array list of tag names, sorted by frequency 114 */ 115 function _gettags( &$thlp ) { 116 $data = array(); 117 if ( !is_array( $thlp->topic_idx ) ) 118 return $data; 119 foreach ( $thlp->topic_idx as $k => $v ) { 120 if ( !is_array( $v ) || empty( $v ) || ( !trim( $v[0] ) ) ) 121 continue; 122 $data[$k] = count( $v ); 123 } 124 arsort( $data ); 125 return ( array_keys( $data ) ); 126 } 127 128 /** 129 * list all pages in the namespace. 130 * 131 * @param $tagns namespace to search. 132 * @return array list of tag names. 133 */ 134 function _getpages( $tagns = 'wiki:tags' ) { 135 global $conf; 136 require_once( DOKU_INC . 'inc/search.php' ); 137 $data = array(); 138 search( $data, $conf['datadir'], array( 139 $this, 140 '_tagentry_search_tagpages' 141 ), array( 142 'ns' => $tagns 143 ) ); 144 return ( $data ); 145 } 146 147 function clipstring( $s, $len = 22 ) { 148 return substr( $s, 0, $len ) . ( ( strlen( $s ) > $len ) ? '..' : '' ); 149 } 150 151 function escapeJSstring( $o ) { 152 return ( // TODO: use JSON ?! 153 str_replace( "\n", '\\n', str_replace( "\r", '', str_replace( '\'', '\\\'', str_replace( '\\', '\\\\', $o ) ) ) ) ); 154 } 155 156 /** case insenstive in_array();. 157 */ 158 function in_iarray( $needle, $haystack ) { 159 if ( !is_array( $haystack ) ) 160 return false; 161 foreach ( $haystack as $t ) { 162 if ( strcasecmp( $needle, $t ) == 0 ) 163 return true; 164 } 165 return false; 166 } 167 168 /** 169 * render and return the tag-select box. 170 * 171 * @param $alltags array of tags to display. 172 * @param $options array 173 * @return string XHTML form. 174 */ 175 function _format_tags( $alltags, $options ) { 176 $rv = ''; 177 if ( !is_array( $alltags ) ){ return $rv; } 178 if ( count( $alltags ) < 1 ){ return $rv; } 179 //$rv .= '<div>'; 180 //$rv .= ' <div><label>' . $this->getLang( 'assign' ) . '</label></div>'; 181 $rv .= '<div class="taglist"' . $dstyle . '>'; 182 //$rv .= '<div>'; 183 184 // Trie les tags 185 natcasesort( $alltags ); 186 187 // Boucle sur les tags 188 $i = 0; 189 foreach ( $alltags as $tagname ) { 190 191 // Blacklist 192 $hasBlacklist = is_array( $options['blacklist'] ); 193 $inBlacklist = $this->in_iarray( $tagname, $options['blacklist'] ); 194 195 if ( $hasBlacklist && $inBlacklist ){ continue; } 196 197 $i++; 198 199 $rv .= '<label><input type="checkbox" id="plugin__tagentry_cb' . $tagname . '"'; 200 $rv .= ' value="1" name="' . $tagname . '"'; 201 if ( $this->in_iarray( $tagname, $options['assigned'] ) ){ 202 $rv .= ' checked="checked"'; 203 } 204 205 $rv .= ' onclick="tagentry_clicktag(\'' . $this->escapeJSstring( $tagname ) . '\', this);"'; 206 207 // MODIF : 23/12/2013 14:43:26 208 $rv .= ' /> ' . $this->_getTagTitle( $tagname ) ; 209 $rv .= '</label>'; 210 //$rv.=' /> '.$this->clipstring($tagname).'</label> '; 211 // MODIF : 23/12/2013 14:43:26 212 213 214 $rv .= "\n"; 215 } 216 217 //$rv .= '</div>'; 218 //$rv .= '</div>'; 219 return ( $rv ); 220 } 221 222 // MODIF : 23/12/2013 14:55:07 223 /** 224 * Return Header title or tag name 225 * @param $tagname The name of tag without namespace 226 * @return Title of the tag page or tag name formatted 227 */ 228 function _getTagTitle( $tagname ) { 229 global $conf; 230 if ( $conf['useheading'] ) { 231 $tagplugin = plugin_load( 'helper', 'tag' ); 232 if ( plugin_isdisabled( 'tag' ) || !$tagplugin ) { 233 msg( 'The Tag Plugin must be installed to display tagentry.', -1 ); 234 return $this->clipstring( $tagname ); 235 } 236 237 $id = $tagname; 238 $exist = false; 239 resolve_pageID( $tagplugin->namespace, $id, $exist ); 240 if ( $exist ) { 241 return p_get_first_heading( $id, false ); 242 } 243 } 244 return $this->clipstring( $tagname ); 245 } 246 // MODIF : 23/12/2013 14:55:07 247} 248