1<?php 2/** 3 * Wiki farm manager 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Etienne MELEARD <etienne.meleard@cru.fr> 7 * @desc Process and renders farm config related requests 8 */ 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 13if(!defined('DOKU_FARM_PLUGIN')) define('DOKU_FARM_PLUGIN', DOKU_PLUGIN.'farm/'); 14 15if(!defined('DOKU_FARMPLUGINLOADED')) define('DOKU_FARMPLUGINLOADED', true); 16 17require_once DOKU_FARM_PLUGIN.'animal.class.php'; 18 19class dokuwiki_farm_config { 20 var $data = array(); 21 var $manager = null; 22 var $errors = array(); 23 private $ref = array(); 24 private $conf = array(); 25 26 /** 27 * @param $manager object that must handle error(), success(), nicesize(), getLang() ... calls 28 */ 29 function __construct($manager) { 30 $this->manager = & $manager; 31 $farmconf = array(); 32 include DOKU_FARM_PLUGIN.'config.php'; 33 $this->data = $farmconf; 34 } 35 36 /** 37 * Process requests 38 */ 39 function process() { 40 if(isset($this->manager->opt['save'])) { 41 // Security check 42 if(!checkSecurityToken()) { 43 $this->manager->error('system_errors', 'system_badtoken_failure'); 44 return; 45 } 46 if(!$this->save()) { 47 $this->manager->error('config_errors', 'config_save_failure'); 48 return; 49 } 50 } 51 } 52 53 /** 54 * Renders 55 */ 56 function html() { 57 ptln('<div class="farm_cmd_title">'.$this->manager->getLang('config_title').'</div>'); 58 ptln('<div class="farm_cmd_info">'.$this->manager->getLang('config_info').'</div>'); 59 $this->form(); 60 } 61 62 /** 63 * Tells whether a configuration parameter is editable 64 * @param $f parameter identifier 65 * @return boolean 66 */ 67 function allowed($f) { 68 if( 69 $f == 'farmwebroot' || 70 $f == 'farmfsroot' || 71 $f == 'farmer' || 72 $f == 'barn' 73 ) return false; 74 return true; 75 } 76 77 /** 78 * Outputs a form to edit the farm configuration 79 */ 80 function form($install = false) { 81 $cnf = array(); 82 foreach(explode("\n", @file_get_contents(DOKU_FARM_PLUGIN.'config.php')) as $l) { 83 if(preg_match('`^\$farmconf\[[\'"]([a-z0-9_-]+)[\'"]\]\s*=\s*([^;]+);$`i', trim($l), $m)) { 84 $id = trim($m[1]); 85 if(!$this->allowed($id)) continue; 86 $d = trim($m[2]); 87 if(preg_match('`^[\'"].*[\'"]$`', $d)) $d = substr($d, 1, -1); 88 if(in_array(strtolower($d), array('true', 'false'))) $d = (strtolower($d) == 'true'); 89 $cnf[$id] = $d; 90 } 91 } 92 93 $this->manager->formHead(array('farm_cmd' => 'farmconfig')); 94 foreach($cnf as $id => $d) { 95 ptln(' <fieldset>'); 96 $l = ' '.$this->manager->getLang('config_field_name_'.$id).' : '; 97 if(is_bool($d)) { 98 $l .= '<input type="checkbox" name="config_field_'.$id.'"'; 99 if($d) $l .= ' checked="checked"'; 100 $l .= '/>'; 101 }else{ 102 $l .= '<input type="text" name="config_field_'.$id.'" value="'.$d.'"/>'; 103 } 104 ptln($l.'<br />'); 105 ptln('<small>'.$this->manager->getLang('config_field_desc_'.$id).'</small>'); 106 ptln(' </fieldset>'); 107 } 108 109 ptln(' <fieldset class="save">'); 110 ptln(' <input type="submit" class="button" name="farm_opt[save]" value="'.$this->manager->getLang('btn_save').'" />'); 111 ptln(' </fieldset>'); 112 ptln('</form>'); 113 } 114 115 /** 116 * Saves the farm configuration 117 * @return success as boolean 118 */ 119 function save() { 120 $this->conf = explode("\n", @file_get_contents(DOKU_FARM_PLUGIN.'config.php')); 121 if(!count($this->conf)) return false; 122 123 for($i=0; $i<count($this->conf); $i++) { 124 if(preg_match('`^\$farmconf\[[\'"]([a-z0-9_-]+)[\'"]\]\s*=\s*([^;]+);$`i', trim($this->conf[$i]), $m)) { 125 $id = trim($m[1]); 126 $this->ref[$id] = $i; 127 } 128 } 129 130 foreach($this->ref as $id => $n) { 131 if(!$this->allowed($id)) continue; 132 if(preg_match('`^\$farmconf\[[\'"]([a-z0-9_-]+)[\'"]\]\s*=\s*([^;]+);$`i', trim($this->conf[$n]), $m)) { 133 $d = trim($m[2]); 134 if(preg_match('`^[\'"].*[\'"]$`', $d)) $d = substr($d, 1, -1); 135 if(in_array(strtolower($d), array('true', 'false'))) { 136 $d = (strtolower($d) == 'true'); 137 if($this->triggerChange($id, $d, isset($_POST['config_field_'.$id]))) $this->conf[$n] = '$farmconf[\''.$id.'\'] = '.(isset($_POST['config_field_'.$id]) ? 'true' : 'false').';'; 138 }elseif(preg_match('`^[0-9]+(\s*[+/*-]\s*[0-9]+)*$`', $d)) { 139 if(!isset($_POST['config_field_'.$id])) continue; 140 $fb = create_function('', 'try{ return '.$d.'; }catch(Exception $e) { return null; }'); 141 $fa = create_function('', 'try{ return '.(!empty($_POST['config_field_'.$id]) ? $_POST['config_field_'.$id] : '0').'; }catch(Exception $e) { return 0; }'); 142 if(is_null($fa())) continue; 143 if($this->triggerChange($id, $fb(), $fa())) $this->conf[$n] = '$farmconf[\''.$id.'\'] = '.$_POST['config_field_'.$id].';'; 144 }else{ 145 if(!isset($_POST['config_field_'.$id])) continue; 146 if($this->triggerChange($id, $d, $_POST['config_field_'.$id])) $this->conf[$n] = '$farmconf[\''.$id.'\'] = \''.str_replace('\'', '\\\'', $_POST['config_field_'.$id]).'\';'; 147 } 148 } 149 } 150 if($fp = fopen(DOKU_FARM_PLUGIN.'config.php', 'w')) { 151 fwrite($fp, implode("\n", $this->conf)); 152 fclose($fp); 153 return true; 154 }else return false; 155 } 156 157 /** 158 * Copy .htaccess replacing some tags 159 * @param $src source file 160 * @param $dest destination file 161 */ 162 function copyHtaccess($src, $dest, $more = array()) { 163 $c = @file_get_contents($src); 164 if(!$c) return false; 165 166 $farm = $this->manager->conf['farmwebroot']; 167 if(preg_match('`^([^:]+://)?([^/]+)?/?(.*)$`i', $farm, $m)) $farm = $m[3]; 168 if(substr($farm, -1) != '/') $farm .= '/'; 169 $c = str_replace('{farm}', $farm, $c); 170 $c = str_replace('{farmer}', $this->manager->conf['farmer'], $c); 171 $c = str_replace('{barn}', $this->manager->conf['barn'], $c); 172 173 foreach($more as $k => $v) $c = str_replace('{'.$k.'}', $v, $c); 174 175 $fp = fopen($dest, 'w'); 176 if(!$fp) return false; 177 fwrite($fp, $c); 178 fclose($fp); 179 return true; 180 } 181 182 /** 183 * Handles some specific parameters changes 184 * @param $id parameter identifier 185 * @param $before value before change 186 * @param $after value after change 187 * @return boolean telling wheter the change is acepted or not 188 */ 189 function triggerChange($id, $before, $after) { 190 if($after === $before) return true; 191 192 if($id == 'farmrewrite') { 193 if($after) { 194 if(realpath($this->manager->conf['farmfsroot'].$this->manager->conf['barn']) == realpath($this->manager->conf['farmfsroot'])) return true; 195 196 if($this->copyHtaccess(DOKU_FARM_PLUGIN.'install/farm.htaccess', $this->manager->conf['farmfsroot'].'.htaccess')) { 197 if($this->triggerChange('userewrite', false, true)) { 198 $_POST['config_field_userewrite'] = 1; // to keep integrity 199 $this->conf[$this->ref['userewrite']] = '$farmconf[\'userewrite\'] = true;'; 200 return true; 201 } 202 return false; 203 }else{ 204 $this->manager->error('config_errors', 'config_createfarmrewritefile_failure'); 205 return false; 206 } 207 }elseif(@file_exists($this->manager->conf['farmfsroot'].'.htaccess')) { 208 if(realpath($this->manager->conf['farmfsroot'].$this->manager->conf['barn']) == realpath($this->manager->conf['farmfsroot'])) return true; 209 if(!unlink($this->manager->conf['farmfsroot'].'.htaccess')) { 210 $this->manager->error('config_errors', 'config_deletefarmrewritefile_failure'); 211 return false; 212 } 213 } 214 return true; 215 } 216 217 if($id == 'userewrite') { 218 if($after) { 219 $src = (realpath($this->manager->conf['farmfsroot'].$this->manager->conf['barn']) != realpath($this->manager->conf['farmfsroot'])) ? 'barn.htaccess' : 'barnatroot.htaccess'; 220 if($this->copyHtaccess(DOKU_FARM_PLUGIN.'install/'.$src, $this->manager->conf['farmfsroot'].$this->manager->conf['barn'].'.htaccess')) { 221 return true; 222 }else{ 223 $this->manager->error('config_errors', 'config_createrewritefile_failure'); 224 return false; 225 } 226 }else{ 227 if(@file_exists($this->manager->conf['farmfsroot'].'.htaccess')) { 228 if(!unlink($this->manager->conf['farmfsroot'].'.htaccess')) { 229 $this->manager->error('config_errors', 'config_deletefarmrewritefile_failure'); 230 }else{ 231 $_POST['config_field_farmrewrite'] = 0; // to keep integrity 232 $this->conf[$this->ref['barnrewrite']] = '$farmconf[\'farmrewrite\'] = false;'; 233 } 234 } 235 if(@file_exists($this->manager->conf['farmfsroot'].$this->manager->conf['barn'].'.htaccess')) { 236 if(!unlink($this->manager->conf['farmfsroot'].$this->manager->conf['barn'].'.htaccess')) { 237 $this->manager->error('config_errors', 'config_deleterewritefile_failure'); 238 return false; 239 } 240 } 241 return true; 242 } 243 } 244 245 if($id == 'virtual') { 246 if($after) { 247 if(!@file_exists(DOKU_FARM_PLUGIN.'virtual_hosts.php')) { 248 if(!copy(DOKU_FARM_PLUGIN.'install/virtual_hosts.php', DOKU_FARM_PLUGIN.'virtual_hosts.php')) { 249 $this->manager->error('config_errors', 'config_copyvirtualhostfile_failure'); 250 return false; 251 } 252 } 253 254 if(!$this->copyHtaccess(DOKU_FARM_PLUGIN.'install/virtual.htaccess', $this->manager->conf['farmfsroot'].'.htaccess', array('farmerhost' => $this->manager->conf['farmerhost']))) { 255 $this->manager->error('config_errors', 'config_createrewritefile_failure'); 256 return false; 257 } 258 }else{ 259 if($this->manager->conf['userewrite']) { 260 if($this->triggerChange('userewrite', false, true)) { 261 $_POST['config_field_userewrite'] = 1; // to keep integrity 262 $this->conf[$this->ref['userewrite']] = '$farmconf[\'userewrite\'] = true;'; 263 } 264 } 265 if($this->manager->conf['farmrewrite']) { 266 if($this->triggerChange('farmrewrite', false, true)) { 267 $_POST['config_field_farmrewrite'] = 1; // to keep integrity 268 $this->conf[$this->ref['farmrewrite']] = '$farmconf[\'farmrewrite\'] = true;'; 269 } 270 } 271 } 272 $this->manager->conf['virtual'] = $after; 273 return true; 274 } 275 276 if($id == 'farmerhost') { 277 if(!$this->manager->conf['virtual']) return true; 278 if($this->copyHtaccess(DOKU_FARM_PLUGIN.'install/virtual.htaccess', $this->manager->conf['farmfsroot'].'.htaccess', array('farmerhost' => $after))) { 279 return true; 280 }else{ 281 $this->manager->error('config_errors', 'config_createrewritefile_failure'); 282 return false; 283 } 284 } 285 286 if($id == 'animaltemplate') { 287 if(!dokuwiki_farm_animal::exists($after)) { 288 $this->manager->error('config_errors', 'animal_unknownanimal_failure'); 289 return false; 290 }else return true; 291 } 292 293 if($id == 'enablesoap') { 294 if($after) { 295 if(!@file_exists($this->manager->conf['farmfsroot'].'farm.wsdl')) { 296 $wsdl = @file_get_contents(DOKU_FARM_PLUGIN.'install/wsdl.base'); 297 if(!$wsdl) { 298 $this->manager->error('config_errors', 'config_createwsdl_failure'); 299 return false; 300 } 301 $file = $this->manager->conf['farmwebroot'].'farm.wsdl'; 302 $wsdl = str_replace('{wsdl}', $file, $wsdl); 303 $wsdl = str_replace('{location}', $this->manager->conf['farmwebroot'].$this->manager->conf['farmer'].'lib/plugins/farm/soapserver.php', $wsdl); 304 if($fp = fopen($this->manager->conf['farmfsroot'].'farm.wsdl', 'w')) { 305 fwrite($fp, $wsdl); 306 fclose($fp); 307 }else{ 308 $this->manager->error('config_errors', 'config_createwsdl_failure'); 309 return false; 310 } 311 } 312 313 if(!@file_exists(DOKU_FARM_PLUGIN.'trusted_apps.php')) { 314 if(!copy(DOKU_FARM_PLUGIN.'install/trusted_apps.php', DOKU_FARM_PLUGIN.'trusted_apps.php')) { 315 $this->manager->error('config_errors', 'config_copytrustedappsfile_failure'); 316 return false; 317 } 318 } 319 }else{ 320 if(@file_exists($this->manager->conf['farmfsroot'].'farm.wsdl')) { 321 if(!unlink($this->manager->conf['farmfsroot'].'farm.wsdl')) { 322 $this->manager->error('config_errors', 'config_deletewsdl_failure'); 323 return false; 324 } 325 } 326 } 327 $this->manager->conf['enablesoap'] = $after; 328 return true; 329 } 330 331 return true; 332 } 333} 334?> 335