summaryrefslogtreecommitdiff
path: root/platform/www/lib/plugins/config/core/Writer.php
diff options
context:
space:
mode:
Diffstat (limited to 'platform/www/lib/plugins/config/core/Writer.php')
-rw-r--r--platform/www/lib/plugins/config/core/Writer.php116
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'),
+ ' */',
+ '',
+ ''
+ )
+ );
+ }
+}