[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 namespace dokuwiki\plugin\config\core; 4 use dokuwiki\plugin\config\core\Setting\Setting; 5 use dokuwiki\Logger; 6 7 /** 8 * Writes the settings to the correct local file 9 */ 10 class Writer { 11 /** @var string header info */ 12 protected $header = 'Dokuwiki\'s Main Configuration File - Local Settings'; 13 14 /** @var string the file where the config will be saved to */ 15 protected $savefile; 16 17 /** 18 * Writer constructor. 19 */ 20 public function __construct() { 21 global $config_cascade; 22 $this->savefile = end($config_cascade['main']['local']); 23 } 24 25 /** 26 * Save the given settings 27 * 28 * @param Setting[] $settings 29 * @throws \Exception 30 */ 31 public function save($settings) { 32 global $conf; 33 if($this->isLocked()) throw new \Exception('no save'); 34 35 // backup current file (remove any existing backup) 36 if(file_exists($this->savefile)) { 37 if(file_exists($this->savefile . '.bak.php')) @unlink($this->savefile . '.bak.php'); 38 if(!io_rename($this->savefile, $this->savefile . '.bak.php')) throw new \Exception('no backup'); 39 } 40 41 if(!$fh = @fopen($this->savefile, 'wb')) { 42 io_rename($this->savefile . '.bak.php', $this->savefile); // problem opening, restore the backup 43 throw new \Exception('no save'); 44 } 45 46 $out = ''; 47 foreach($settings as $setting) { 48 if($setting->shouldBeSaved()) { 49 $out .= $setting->out('conf', 'php'); 50 } 51 } 52 53 if($out === '') { 54 throw new \Exception('empty config'); 55 } 56 $out = $this->getHeader() . $out; 57 58 fwrite($fh, $out); 59 fclose($fh); 60 if($conf['fperm']) chmod($this->savefile, $conf['fperm']); 61 $this->opcacheUpdate($this->savefile); 62 } 63 64 /** 65 * Update last modified time stamp of the config file 66 * 67 * Will invalidate all DokuWiki caches 68 * 69 * @throws \Exception when the config isn't writable 70 */ 71 public function touch() { 72 if($this->isLocked()) throw new \Exception('no save'); 73 @touch($this->savefile); 74 $this->opcacheUpdate($this->savefile); 75 } 76 77 /** 78 * Invalidate the opcache of the given file (if possible) 79 * 80 * @todo this should probably be moved to core 81 * @param string $file 82 */ 83 protected function opcacheUpdate($file) { 84 if(!function_exists('opcache_invalidate')) return; 85 set_error_handler(function ($errNo, $errMsg) { 86 Logger::debug('Unable to invalidate opcache: ' . $errMsg); } 87 ); 88 opcache_invalidate($file); 89 restore_error_handler(); 90 } 91 92 /** 93 * Configuration is considered locked if there is no local settings filename 94 * or the directory its in is not writable or the file exists and is not writable 95 * 96 * @return bool true: locked, false: writable 97 */ 98 public function isLocked() { 99 if(!$this->savefile) return true; 100 if(!is_writable(dirname($this->savefile))) return true; 101 if(file_exists($this->savefile) && !is_writable($this->savefile)) return true; 102 return false; 103 } 104 105 /** 106 * Returns the PHP intro header for the config file 107 * 108 * @return string 109 */ 110 protected function getHeader() { 111 return join( 112 "\n", 113 array( 114 '<?php', 115 '/*', 116 ' * ' . $this->header, 117 ' * Auto-generated by config plugin', 118 ' * Run for user: ' . (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : 'Unknown'), 119 ' * Date: ' . date('r'), 120 ' */', 121 '', 122 '' 123 ) 124 ); 125 } 126 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body