1<?php 2/** 3 * 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Myron Turner <turnermm02@shaw.ca> 7 */ 8 9 10/** 11 * All DokuWiki plugins to extend the admin function 12 * need to inherit from this class 13 */ 14class admin_plugin_snippets extends DokuWiki_Admin_Plugin { 15 16 private $output = ''; 17 private $metaFn; 18 private $debug; 19 20 function __construct() { 21 $metafile= 'snippets_upd'; 22 $this->metaFn = metaFN($metafile,'.ser'); 23 $this->debug = false; 24 } 25 /** 26 * handle user request 27 */ 28 function handle() { 29 30 if (!isset($_REQUEST['cmd'])) return; // first time - nothing to do 31 32 $this->output = 'invalid'; 33 34 if (!checkSecurityToken()) return; 35 if (!is_array($_REQUEST['cmd'])) return; 36 37 // verify valid values 38 switch (key($_REQUEST['cmd'])) { 39 case 'prune' : 40 $this->output = 'prune'; 41 break; 42 case 'docs' : 43 $this->output = 'doc'; 44 // $this->secure_datafile() ; 45 break; 46 } 47 48 49 } 50 51 /** 52 * output appropriate html 53 */ 54 function html() { 55 ptln('<a href="javascript:snippets_Inf.toggle();void 0"><span style="line-height: 175%">Toggle info</span></a><br />'); 56 ptln('<div id="prereg_info" style="border: 1px solid silver; padding:4px;">'. $this->locale_xhtml('info') . '</div><br>' ); 57 58 59 ptln('<form action="'.wl($ID).'" method="post">'); 60 61 // output hidden values to ensure dokuwiki will return back to this plugin 62 ptln(' <input type="hidden" name="do" value="admin" />'); 63 ptln(' <input type="hidden" name="page" value="'.$this->getPluginName().'" />'); 64 formSecurityToken(); 65 66 $but_1 = $this->getLang('cleanup_but')| 'START'; 67 ptln(' <input type="submit" name="cmd[docs]" value="'. $but_1.'" />'); 68 ptln('<br /><br /><div>'); 69 70 if($this->output == 'doc') { 71 echo $this->prune_datafile('doc'); 72 } 73 74 ptln('</div>'); 75 ptln('</form>'); 76 $this->js(); 77 } 78 79 80 function prune_datafile() { 81 $ret = '<b>'. $this->getLang("dbase") . '</b>' . $this->metaFn; 82 $data_all = unserialize(io_readFile($this->metaFn,false)); 83 $data = $data_all['doc']; 84 $snip_data = array(); 85 if (!is_array($data)) $data = array(); 86 foreach($data as $id=>$snips) { 87 $ar = array(); // will hold snips currently in page file 88 $found = $this->update_all($id, $snips, $ar) ; 89 $ret .= '<br /><h2>id: ' . $id .'</h2>'; 90 $snips =implode('<br />',$snips); 91 92 $ret .= "<b><u>" . $this->getLang("logged_for") ." $id:</u></b><br />$snips<br /><b>" . $this->getLang("in_page") ."</b><br />$found<br />"; 93 $data[$id] = $ar; 94 for($i=0; $i<count($ar); $i++) { 95 $snip_data[$ar[$i]][] = $id; 96 } 97 } 98 $final = array(); 99 $final['doc'] = $data; 100 $final['snip'] = $snip_data; 101 io_saveFile($this->metaFn,serialize($final)); 102 return $ret; 103 } 104 105 function update_all($id, $snips, &$ar) { 106 $file=wikiFN($id); 107 $text = file_get_contents($file); 108 preg_match_all("/~~SNIPPET_C~~(.*?)~~/",$text,$matches); 109 $ar = $matches[1]; 110 preg_match_all("/~~SNIPPET_O(.*?)~~(.*?)~~/",$text,$matches_tm); 111 112 $page_entries = array(); 113 for($i=0; $i<count($matches_tm[1]);$i++) { 114 $tm = $matches_tm[1][$i]; 115 $sfile = $matches_tm[2][$i]; 116 $res .= " <b>$sfile</b> timestamp: " . $tm . ", date: " .date('r', $tm) . "<br />"; 117 $page_entries[$sfile] = $tm; 118 } 119 120 /* from metafile */ 121 $isref = p_get_metadata($id, 'relation isreferencedby'); 122 $res .= '<br /><b>' .$this->getLang("in_meta") . '</b><br />'; 123 $refs = $isref['snippets']; 124 foreach ($refs as $fnam=>$tm) { 125 $res .= "$fnam: " .date('r', $tm) . '<br />'; 126 } 127 $refs_keys = array_keys($refs); 128 //get snippets in $refs_keys which are not in matches[1], i.e snips in metafile which are not in page file 129 $refs_diff_1 = array_diff($refs_keys,$matches[1]); 130 $refs_diff_2 = array_diff($matches[1],$refs_keys); 131 if(!empty( $refs_diff_1 )) 132 $res .= $this->dbg('<b>Snippets in metafile not in page:</b><br /> ', $refs_diff_1,"132") ; 133 else $res .= $this->dbg("No snippets found in metafile not in page","133"); 134 if(!empty($refs_diff_2)) { 135 $res .= $this->dbg('<b>Snippets in page not in meta file:</b><br /> ', $refs_diff_2,"135"); 136 } 137 else $res .= $this->dbg("No snippets found in page which are not logged in metafile","137"); 138 139 $res .= $this->update_metafile($refs_diff_2,$refs_diff_1,$id, $matches_tm[1][0] ,$page_entries); 140 141 $diff = array_diff($snips,$matches[1]) ; 142 if(empty($diff)) { 143 $diff = $this->getLang('finished'); 144 } 145 else $diff = implode('<br />',$diff); 146 147 $res .= "<br><b>" . $this->getLang("remove_from_db") . "</b></br>" . $diff; 148 return $res; 149 } 150 151 function update_metafile($add_array,$remove_array, $id,$tm,$page_ar ) { 152 $ret =""; 153 154 $to_add = false; 155 $to_remove = false; 156 if(empty($add_array) && empty($remove_array)) return "Nothing to be done for $id<br />"; 157 $isref = p_get_metadata($id, 'relation isreferencedby'); 158 if(!empty($add_array)) { 159 $to_add = true; 160 $ret .= $this->dbg('Add to metafile: ',$add_array); 161 } 162 else $ret .=$this->dbg("No additions to metafile '","163"); 163 164 if(!empty($remove_array)) { 165 $to_remove=true; 166 $ret .= $this->dbg('Remove from metafile ', $remove_array,"167"); 167 } 168 else $ret .=$this->dbg("No snippets to remove from metafile"); 169 170 $snippet_array = $isref['snippets']; 171 $ret .= $this->dbg('metafile snippet_array: ', $snippet_array,"172"); 172 $ret .= "<b>" . $this->getLang("updating_mf")."</b><br/>"; 173 if($to_remove) { 174 $ret .= "<b>" . $this->getLang("removing"). "</b><br/>"; 175 foreach($snippet_array as $snippet=>$date) { 176 if(in_array($snippet,$remove_array)) { 177 $ret .= " $snippet<br />"; 178 continue; 179 } 180 $updated['snippets'][$snippet]=$date; 181 } 182 $ret .= "<br/>"; 183 if(count($updated)) { 184 $ret .= $this->dbg('updated: ', $updated,"185"); 185 } 186 else $ret .= $this->dbg('No snippets remaining in ' . $id); 187 } 188 189 if($to_add) { 190 $ret .="<b>" . $this->getLang("adding") . "</b><br />"; 191 foreach($add_array as $add){ 192 $updated ['snippets'] [$add] =$tm; 193 $ret .= " $add<br />"; 194 } 195 } 196 197 198 // merge page entries with updates 199 foreach($page_ar as $snip=>$tm) { 200 if(!array_key_exists ( $snip , $updated ['snippets'] )) { 201 $updated ['snippets'][$snip] = $tm; 202 } 203 } 204 205 $ret .= $this->getLang("updated") . print_r($updated ,1) . "<br />"; 206 207 $data['relation']['isreferencedby']['snippets']=$updated['snippets']; 208 p_set_metadata($id, $data); 209 return $ret; 210 211 } 212 213 function dbg($text, $ar = array(),$line="") { 214 if(!$this->debug) return; 215 if($ar) { 216 $text .= print_r( $ar, 1); 217 } 218 if($line) $text .= " [$line]"; 219 return "dbg: " . $text . "<br />"; 220 } 221 222 function js() { 223echo <<<SCRIPT 224<script type="text/javascript"> 225 //<![CDATA[ 226var snippets_Inf = { 227dom_style: document.getElementById('prereg_info').style, 228open: function() { this.dom_style.display = 'block'; }, 229close: function() { this.dom_style.display = "none"; }, 230toggle: function() { 231if(this.is_open) { this.close(); this.is_open=false; return; } 232this.open(); this.is_open=true; 233}, 234is_open: true, 235}; 236 //]]> 237 </script> 238SCRIPT; 239 240 } 241}