1<?php 2/** 3 * Remove outdated files after upgrade -> administration function 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Taggic <taggic@t-online.de> 7 */ 8/******************************************************************************/ 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12/******************************************************************************/ 13/** 14 * All DokuWiki plugins to extend the admin function 15 * need to inherit from this class 16 */ 17class admin_plugin_removeold extends DokuWiki_Admin_Plugin { 18 /** 19 * return some info 20 */ 21 function getInfo(){ 22 return confToHash(dirname(__FILE__).'/plugin.info.txt'); 23 } 24/******************************************************************************/ 25 /** 26 * return prompt for admin menu 27 */ 28 function getMenuText($language) { 29 return $this->getLang('admin_removeold'); 30 } 31/******************************************************************************/ 32 /** 33 * return sort order for position in admin menu 34 */ 35 function getMenuSort() { 36 return 20; 37 } 38/******************************************************************************/ 39 /** 40 * handle user request 41 * 42 * Initializes internal vars and handles modifications 43 * 44 * @author Taggic <taggic@t-online.de> 45 */ 46 function handle() { 47 global $ID; 48 } 49/******************************************************************************/ 50 /** 51 * removeold Output function 52 * 53 * print a table with all found lanuage folders 54 * 55 * @author Taggic <taggic@t-online.de> 56 */ 57 function html() { 58 global $ID; 59 60 echo '<div id="removeold__manager">'.NL; 61 echo '<h1>'.$this->getLang('admin_removeold').'</h1>'.NL; 62 echo '<div class="level1">'.NL; 63 64 echo '<div id="removeold__intro">'.NL; 65 echo $this->locale_xhtml('help'); 66 echo '</div>'.NL; 67 68 echo '<div id="removeold__detail">'.NL; 69 $this->_html_uinput(); 70 echo '</div>'.NL; 71 72 $filelist = $_REQUEST['removeold_w']; 73 $dryrun = $_REQUEST['dryrun']; 74 $summary_option = $_REQUEST['summary_only']; 75 76 // language given? 77 if ($filelist!=false) { 78 if (($dryrun==true) && ($summary_option==false)) { 79 echo '<br /><div class="level4"><strong><div class="it__standard_feedback">'.$this->getLang('removeold_willmsg').'</div></strong><br />'; 80 } 81 elseif ($summary_option==false) { 82 echo '<br /><div class="level4"><strong><div class="it__standard_feedback">'.$this->getLang('removeold_delmsg').'</div></strong><br />'; 83 } 84 85 $this->_list_removeold_files($filelist, $dryrun, $summary_option); 86 } 87 echo '</div>'.NL; 88 echo '<div class="footnotes"><div class="fn">'.NL; 89 echo '<sup><a id="fn__1" class="fn_bot" name="fn__1" href="#fnt__1">1)</a></sup>'.NL; 90 echo $this->getLang('p_include'); 91 echo '</div></div>'.NL; 92 93 echo '</div>'.NL; 94 } 95/******************************************************************************/ 96 /** 97 * Display the form with input control to let the user specify 98 * the files to be deleted 99 * 100 * @author Taggic <taggic@t-online.de> 101 */ 102 function _html_uinput(){ 103 global $conf; 104 global $ID; 105 106 // load deleted.files from data folder and show it in textarea 107 if(is_dir($conf["savedir"])=== false) { 108 $deleted_files = file_get_contents(DOKU_INC."/".$conf["savedir"]."/deleted.files"); 109 } 110 else $deleted_files = file_get_contents($conf["savedir"]."/deleted.files"); 111 112 if($deleted_files !== "") { 113 echo '<div class="level4" id="removeold__input">'.$this->getLang('i_choose').'<br />'.NL; 114 echo '<div class="no">'.NL; 115 echo '<fieldset class="removeold__fieldset"><legend class="removeold_i_legend">'.$this->getLang('i_legend').'</legend>'.NL; 116 echo '<form action="'.wl($ID).'" method="post">'; 117 echo '<input type="hidden" name="do" value="admin" />'.NL; 118 echo '<input type="hidden" name="page" value="removeold" />'.NL; 119 echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'.NL; 120 echo '<div class="removeold__divinput">'; 121 echo '<textarea type="text" name="removeold_w" class="edit removeold_edit" value="'.$_REQUEST['removeold_w'].'" rows="20" cols="50" />'.$deleted_files.'</textarea><br />'.NL; 122 echo '<input type="checkbox" name="dryrun" checked="checked"> '.$this->getLang('i_dryrun').' </input><br />'.NL; 123 echo '<input type="checkbox" name="summary_only" > '.$this->getLang('summary_option').' </input><br />'.NL; 124 echo '<div class="removeold__divright">'; 125 echo '<input type="submit" value="'.$this->getLang('btn_start').'" class="button"/>'; 126 echo '</div>'.NL; 127 echo '</div>'.NL; 128 echo '</form>'.NL; 129 echo '</fieldset>'; 130 echo '</div>'.NL; 131 echo '</div>'.NL; 132 echo '<div style="clear:both"></div>'.NL; 133 } 134 else { 135 msg("File not found: ".$deleted_files,-1); 136 } 137 } 138 139/******************************************************************************/ 140 /** 141 * This function will loop through the given files. 142 * It checks if the entry is not empty or comment and if such a file does exist. 143 * If the file does exist then it will be deleted. The result will be stored 144 * into the filelist array for user feddback. 145 */ 146 function _list_removeold_files($afilelist, $dryrun, $summary_option){ 147 # statistic counters 148 # $empty = count empty lines 149 # $comments = count comments 150 # $files_found = count existing files 151 # $files_notFound = count missing files 152 # $files_deleted = count deleted files 153 # $files_delError = count files impossible to delete 154 155 $filelist = explode(chr(10),$afilelist); 156 echo '<div class="level4" id="removeold__input"><p>'.NL; 157 158 foreach($filelist as &$file) { 159 $file = trim($file); 160 # check if item is empty => continue, do nothing 161 if(strlen($file)<1) { $empty++; continue; } 162 # check if item is comment => continue, do nothing 163 if(stripos($file,"#")===0) { $comments++; continue; } 164 # check if file does exist 165 if(file_exists(DOKU_INC.$file)===true) { 166 # delete file (except on dryrun) 167 $files_found++; 168 $result = $this->getLang('exists'); 169 170 if(($dryrun==true) && ($this->is__writable(DOKU_INC.$file)==true)) { 171 $result = $this->getLang('deleted'); 172 $files_deleted++; 173 } 174 elseif(($dryrun==true) && ($this->is__writable(DOKU_INC.$file)===false)) { 175 $result = $this->getLang('delError'); 176 $files_delError++; 177 } 178 179 if($dryrun==false) { 180 $result = unlink(DOKU_INC.$file); 181 if($result === true) { 182 $result = $this->getLang('deleted'); 183 $files_deleted++; 184 } 185 else { 186 $result = $this->getLang('delError'); 187 $files_delError++; 188 } 189 } 190 } 191 else { 192 # file not found 193 $result = $this->getLang('not_found'); 194 } 195 # echo file and result 196 if($summary_option==false) { 197 echo DOKU_INC.$file."<span style=\"float:right;\">".$result."</span><br />".NL; 198 } 199 # write log on delete and error if execution mode 200 if(($result===$this->getLang('delError')) || ($result === $this->getLang('deleted'))) { 201 if($dryrun==false) $this->__removeold_logging($file, $result); 202 } 203 } 204 echo '</p></div><br />'.NL; 205 echo '<div class="level4"><strong><div class="it__standard_feedback">'.$this->getLang('removeold_summary').'</div></strong>'; 206 echo '<div class="level2">'.NL; 207 echo '<table><tr><td>'.$this->getLang('exists').': </td><td>'.$files_found.'</td></tr>'.NL; 208 echo '<tr><td>'.$this->getLang('deleted').': </td><td>'.$files_deleted.'</td></tr>'.NL; 209 echo '<tr><td>'.$this->getLang('delError').' </td><td>'.$files_delError.'</td></tr></table>'.NL; 210 211 echo '</div><br />'.NL; 212 } 213/******************************************************************************/ 214# Since looks like the Windows ACLs bug "wont fix" 215# (see http://bugs.php.net/bug.php?id=27609) 216# alternative function proposed on php.net: 217 function is__writable($path) { 218 if ($path{strlen($path)-1}=='/') 219 return is__writable($path.uniqid(mt_rand()).'.tmp'); 220 221 if (file_exists($path)) { 222 if (!($f = @fopen($path, 'r+'))) 223 return false; 224 fclose($f); 225 return true; 226 } 227 228 if (!($f = @fopen($path, 'w'))) 229 return false; 230 fclose($f); 231 unlink($path); 232 return true; 233 } 234/******************************************************************************/ 235/* logging of deleted files and deletion errors */ 236 function __removeold_logging($file, $result) { 237 global $conf; 238 $timestamp = date('d/M/Y G:i:s'); 239 if(is_dir($conf["savedir"])=== false) { 240 $log_file = DOKU_INC."/".$conf["savedir"].'/tmp/removeold.log'; 241 } 242 else $log_file = $conf["savedir"].'/tmp/removeold.log'; 243 244 $record = "[".$timestamp."]".chr(9).$result.chr(9).chr(9).$file.chr(10); 245 246 // Save logging records 247 $fh = fopen($log_file, 'a+'); 248 if (!fwrite($fh, $record)) { 249 echo "<span style=\"color:red;\">".$this->getLang('ro_err_msg')."</span><br />".NL; 250 } 251 fclose($fh); 252 } 253/******************************************************************************/ 254} 255