はじまりの大地
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core;
|
||||
|
||||
use dokuwiki\plugin\config\core\Setting\Setting;
|
||||
use dokuwiki\Logger;
|
||||
|
||||
/**
|
||||
* 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 = '';
|
||||
foreach ($settings as $setting) {
|
||||
if ($setting->shouldBeSaved()) {
|
||||
$out .= $setting->out('conf', 'php');
|
||||
}
|
||||
}
|
||||
|
||||
if ($out === '') {
|
||||
throw new \Exception('empty config');
|
||||
}
|
||||
$out = $this->getHeader() . $out;
|
||||
|
||||
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 (if possible)
|
||||
*
|
||||
* @todo this should probably be moved to core
|
||||
* @param string $file
|
||||
*/
|
||||
protected function opcacheUpdate($file)
|
||||
{
|
||||
if (!function_exists('opcache_invalidate')) return;
|
||||
set_error_handler(function ($errNo, $errMsg) {
|
||||
Logger::debug('Unable to invalidate opcache: ' . $errMsg);
|
||||
});
|
||||
opcache_invalidate($file);
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 implode(
|
||||
"\n",
|
||||
[
|
||||
'<?php',
|
||||
'/*',
|
||||
' * ' . $this->header,
|
||||
' * Auto-generated by config plugin',
|
||||
' * Run for user: ' . ($_SERVER['REMOTE_USER'] ?? 'Unknown'),
|
||||
' * Date: ' . date('r'),
|
||||
' */',
|
||||
'',
|
||||
''
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user