xref: /dokuwiki/lib/plugins/config/core/Writer.php (revision 5a38a129ffe7e1949e690730ee9157988de617c0)
1*5a38a129SAndreas Gohr<?php
2*5a38a129SAndreas Gohr
3*5a38a129SAndreas Gohrnamespace dokuwiki\plugin\config\core;
4*5a38a129SAndreas Gohr
5*5a38a129SAndreas Gohr/**
6*5a38a129SAndreas Gohr * Writes the settings to the correct local file
7*5a38a129SAndreas Gohr */
8*5a38a129SAndreas Gohrclass Writer {
9*5a38a129SAndreas Gohr    /** @var string header info */
10*5a38a129SAndreas Gohr    protected $header = 'Dokuwiki\'s Main Configuration File - Local Settings';
11*5a38a129SAndreas Gohr
12*5a38a129SAndreas Gohr    /** @var string the file where the config will be saved to */
13*5a38a129SAndreas Gohr    protected $savefile;
14*5a38a129SAndreas Gohr
15*5a38a129SAndreas Gohr    /**
16*5a38a129SAndreas Gohr     * Writer constructor.
17*5a38a129SAndreas Gohr     */
18*5a38a129SAndreas Gohr    public function __construct() {
19*5a38a129SAndreas Gohr        global $config_cascade;
20*5a38a129SAndreas Gohr        $this->savefile = end($config_cascade['main']['local']);
21*5a38a129SAndreas Gohr    }
22*5a38a129SAndreas Gohr
23*5a38a129SAndreas Gohr    /**
24*5a38a129SAndreas Gohr     * Save the given settings
25*5a38a129SAndreas Gohr     *
26*5a38a129SAndreas Gohr     * @param Setting[] $settings
27*5a38a129SAndreas Gohr     * @throws \Exception
28*5a38a129SAndreas Gohr     */
29*5a38a129SAndreas Gohr    public function save($settings) {
30*5a38a129SAndreas Gohr        global $conf;
31*5a38a129SAndreas Gohr        if($this->isLocked()) throw new \Exception('no save');
32*5a38a129SAndreas Gohr
33*5a38a129SAndreas Gohr        // backup current file (remove any existing backup)
34*5a38a129SAndreas Gohr        if(file_exists($this->savefile)) {
35*5a38a129SAndreas Gohr            if(file_exists($this->savefile . '.bak')) @unlink($this->savefile . '.bak');
36*5a38a129SAndreas Gohr            if(!io_rename($this->savefile, $this->savefile . '.bak')) throw new \Exception('no backup');
37*5a38a129SAndreas Gohr        }
38*5a38a129SAndreas Gohr
39*5a38a129SAndreas Gohr        if(!$fh = @fopen($this->savefile, 'wb')) {
40*5a38a129SAndreas Gohr            io_rename($this->savefile . '.bak', $this->savefile); // problem opening, restore the backup
41*5a38a129SAndreas Gohr            throw new \Exception('no save');
42*5a38a129SAndreas Gohr        }
43*5a38a129SAndreas Gohr
44*5a38a129SAndreas Gohr        $out = $this->getHeader();
45*5a38a129SAndreas Gohr        foreach($settings as $setting) {
46*5a38a129SAndreas Gohr            $out .= $setting->out('conf', 'php');
47*5a38a129SAndreas Gohr        }
48*5a38a129SAndreas Gohr
49*5a38a129SAndreas Gohr        fwrite($fh, $out);
50*5a38a129SAndreas Gohr        fclose($fh);
51*5a38a129SAndreas Gohr        if($conf['fperm']) chmod($this->savefile, $conf['fperm']);
52*5a38a129SAndreas Gohr        @opcache_invalidate($this->savefile);
53*5a38a129SAndreas Gohr    }
54*5a38a129SAndreas Gohr
55*5a38a129SAndreas Gohr    /**
56*5a38a129SAndreas Gohr     * Update last modified time stamp of the config file
57*5a38a129SAndreas Gohr     *
58*5a38a129SAndreas Gohr     * Will invalidate all DokuWiki caches
59*5a38a129SAndreas Gohr     *
60*5a38a129SAndreas Gohr     * @throws \Exception when the config isn't writable
61*5a38a129SAndreas Gohr     */
62*5a38a129SAndreas Gohr    public function touch() {
63*5a38a129SAndreas Gohr        if($this->isLocked()) throw new \Exception('no save');
64*5a38a129SAndreas Gohr        @touch($this->savefile);
65*5a38a129SAndreas Gohr        @opcache_invalidate($this->savefile);
66*5a38a129SAndreas Gohr    }
67*5a38a129SAndreas Gohr
68*5a38a129SAndreas Gohr    /**
69*5a38a129SAndreas Gohr     * Configuration is considered locked if there is no local settings filename
70*5a38a129SAndreas Gohr     * or the directory its in is not writable or the file exists and is not writable
71*5a38a129SAndreas Gohr     *
72*5a38a129SAndreas Gohr     * @return bool true: locked, false: writable
73*5a38a129SAndreas Gohr     */
74*5a38a129SAndreas Gohr    public function isLocked() {
75*5a38a129SAndreas Gohr        if(!$this->savefile) return true;
76*5a38a129SAndreas Gohr        if(!is_writable(dirname($this->savefile))) return true;
77*5a38a129SAndreas Gohr        if(file_exists($this->savefile) && !is_writable($this->savefile)) return true;
78*5a38a129SAndreas Gohr        return false;
79*5a38a129SAndreas Gohr    }
80*5a38a129SAndreas Gohr
81*5a38a129SAndreas Gohr    /**
82*5a38a129SAndreas Gohr     * Returns the PHP intro header for the config file
83*5a38a129SAndreas Gohr     *
84*5a38a129SAndreas Gohr     * @return string
85*5a38a129SAndreas Gohr     */
86*5a38a129SAndreas Gohr    protected function getHeader() {
87*5a38a129SAndreas Gohr        return join(
88*5a38a129SAndreas Gohr            "\n",
89*5a38a129SAndreas Gohr            array(
90*5a38a129SAndreas Gohr                '<?php',
91*5a38a129SAndreas Gohr                '/*',
92*5a38a129SAndreas Gohr                ' * ' . $this->header,
93*5a38a129SAndreas Gohr                ' * Auto-generated by config plugin',
94*5a38a129SAndreas Gohr                ' * Run for user: ' . $_SERVER['REMOTE_USER'],
95*5a38a129SAndreas Gohr                ' * Date: ' . date('r'),
96*5a38a129SAndreas Gohr                ' */',
97*5a38a129SAndreas Gohr                '',
98*5a38a129SAndreas Gohr                ''
99*5a38a129SAndreas Gohr            )
100*5a38a129SAndreas Gohr        );
101*5a38a129SAndreas Gohr    }
102*5a38a129SAndreas Gohr}
103