diff options
Diffstat (limited to 'platform/www/lib/plugins/config/core/Writer.php')
-rw-r--r-- | platform/www/lib/plugins/config/core/Writer.php | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/platform/www/lib/plugins/config/core/Writer.php b/platform/www/lib/plugins/config/core/Writer.php new file mode 100644 index 0000000..56de621 --- /dev/null +++ b/platform/www/lib/plugins/config/core/Writer.php @@ -0,0 +1,116 @@ +<?php + +namespace dokuwiki\plugin\config\core; +use dokuwiki\plugin\config\core\Setting\Setting; + +/** + * Writes the settings to the correct local file + */ +class Writer { + /** @var string header info */ + protected $header = 'Dokuwiki\'s Main Configuration File - Local Settings'; + + /** @var string the file where the config will be saved to */ + protected $savefile; + + /** + * Writer constructor. + */ + public function __construct() { + global $config_cascade; + $this->savefile = end($config_cascade['main']['local']); + } + + /** + * Save the given settings + * + * @param Setting[] $settings + * @throws \Exception + */ + public function save($settings) { + global $conf; + if($this->isLocked()) throw new \Exception('no save'); + + // backup current file (remove any existing backup) + if(file_exists($this->savefile)) { + if(file_exists($this->savefile . '.bak.php')) @unlink($this->savefile . '.bak.php'); + if(!io_rename($this->savefile, $this->savefile . '.bak.php')) throw new \Exception('no backup'); + } + + if(!$fh = @fopen($this->savefile, 'wb')) { + io_rename($this->savefile . '.bak.php', $this->savefile); // problem opening, restore the backup + throw new \Exception('no save'); + } + + $out = $this->getHeader(); + foreach($settings as $setting) { + if($setting->shouldBeSaved()) { + $out .= $setting->out('conf', 'php'); + } + } + + fwrite($fh, $out); + fclose($fh); + if($conf['fperm']) chmod($this->savefile, $conf['fperm']); + $this->opcacheUpdate($this->savefile); + } + + /** + * Update last modified time stamp of the config file + * + * Will invalidate all DokuWiki caches + * + * @throws \Exception when the config isn't writable + */ + public function touch() { + if($this->isLocked()) throw new \Exception('no save'); + @touch($this->savefile); + $this->opcacheUpdate($this->savefile); + } + + /** + * Invalidate the opcache of the given file + * + * @todo this should probably be moved to core + * @param string $file + */ + protected function opcacheUpdate($file) { + if(!function_exists('opcache_invalidate')) return; + opcache_invalidate($file); + } + + /** + * Configuration is considered locked if there is no local settings filename + * or the directory its in is not writable or the file exists and is not writable + * + * @return bool true: locked, false: writable + */ + public function isLocked() { + if(!$this->savefile) return true; + if(!is_writable(dirname($this->savefile))) return true; + if(file_exists($this->savefile) && !is_writable($this->savefile)) return true; + return false; + } + + /** + * Returns the PHP intro header for the config file + * + * @return string + */ + protected function getHeader() { + return join( + "\n", + array( + '<?php', + '/*', + ' * ' . $this->header, + ' * Auto-generated by config plugin', + ' * Run for user: ' . $_SERVER['REMOTE_USER'], + ' * Date: ' . date('r'), + ' */', + '', + '' + ) + ); + } +} |