117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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'),
 | 
						|
                ' */',
 | 
						|
                '',
 | 
						|
                ''
 | 
						|
            )
 | 
						|
        );
 | 
						|
    }
 | 
						|
}
 |