[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/plugins/config/core/ -> Writer.php (source)

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