[ 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 = $this->getHeader();
  47          foreach($settings as $setting) {
  48              if($setting->shouldBeSaved()) {
  49                  $out .= $setting->out('conf', 'php');
  50              }
  51          }
  52  
  53          fwrite($fh, $out);
  54          fclose($fh);
  55          if($conf['fperm']) chmod($this->savefile, $conf['fperm']);
  56          $this->opcacheUpdate($this->savefile);
  57      }
  58  
  59      /**
  60       * Update last modified time stamp of the config file
  61       *
  62       * Will invalidate all DokuWiki caches
  63       *
  64       * @throws \Exception when the config isn't writable
  65       */
  66      public function touch() {
  67          if($this->isLocked()) throw new \Exception('no save');
  68          @touch($this->savefile);
  69          $this->opcacheUpdate($this->savefile);
  70      }
  71  
  72      /**
  73       * Invalidate the opcache of the given file (if possible)
  74       *
  75       * @todo this should probably be moved to core
  76       * @param string $file
  77       */
  78      protected function opcacheUpdate($file) {
  79          if(!function_exists('opcache_invalidate')) return;
  80          set_error_handler(function ($errNo, $errMsg) {
  81              Logger::debug('Unable to invalidate opcache: ' . $errMsg); }
  82          );
  83          opcache_invalidate($file);
  84          restore_error_handler();
  85      }
  86  
  87      /**
  88       * Configuration is considered locked if there is no local settings filename
  89       * or the directory its in is not writable or the file exists and is not writable
  90       *
  91       * @return bool true: locked, false: writable
  92       */
  93      public function isLocked() {
  94          if(!$this->savefile) return true;
  95          if(!is_writable(dirname($this->savefile))) return true;
  96          if(file_exists($this->savefile) && !is_writable($this->savefile)) return true;
  97          return false;
  98      }
  99  
 100      /**
 101       * Returns the PHP intro header for the config file
 102       *
 103       * @return string
 104       */
 105      protected function getHeader() {
 106          return join(
 107              "\n",
 108              array(
 109                  '<?php',
 110                  '/*',
 111                  ' * ' . $this->header,
 112                  ' * Auto-generated by config plugin',
 113                  ' * Run for user: ' . (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : 'Unknown'),
 114                  ' * Date: ' . date('r'),
 115                  ' */',
 116                  '',
 117                  ''
 118              )
 119          );
 120      }
 121  }