[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/lib/plugins/config/ -> admin.php (source)

   1  <?php
   2  
   3  /**
   4   * Configuration Manager admin plugin
   5   *
   6   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   7   * @author     Christopher Smith <chris@jalakai.co.uk>
   8   * @author     Ben Coburn <btcoburn@silicodon.net>
   9   */
  10  
  11  use dokuwiki\Extension\AdminPlugin;
  12  use dokuwiki\plugin\config\core\Configuration;
  13  use dokuwiki\plugin\config\core\Setting\Setting;
  14  use dokuwiki\plugin\config\core\Setting\SettingFieldset;
  15  use dokuwiki\plugin\config\core\Setting\SettingHidden;
  16  
  17  /**
  18   * All DokuWiki plugins to extend the admin function
  19   * need to inherit from this class
  20   */
  21  class admin_plugin_config extends AdminPlugin
  22  {
  23      protected const IMGDIR = DOKU_BASE . 'lib/plugins/config/images/';
  24  
  25      /** @var Configuration */
  26      protected $configuration;
  27  
  28      /** @var bool were there any errors in the submitted data? */
  29      protected $hasErrors = false;
  30  
  31      /** @var bool have the settings translations been loaded? */
  32      protected $promptsLocalized = false;
  33  
  34  
  35      /**
  36       * handle user request
  37       */
  38      public function handle()
  39      {
  40          global $ID, $INPUT;
  41  
  42          // always initialize the configuration
  43          $this->configuration = new Configuration();
  44  
  45          if (!$INPUT->bool('save') || !checkSecurityToken()) {
  46              return;
  47          }
  48  
  49          // don't go any further if the configuration is locked
  50          if ($this->configuration->isLocked()) return;
  51  
  52          // update settings and redirect of successful
  53          $ok = $this->configuration->updateSettings($INPUT->arr('config'));
  54          if ($ok) { // no errors
  55              try {
  56                  if ($this->configuration->hasChanged()) {
  57                      $this->configuration->save();
  58                  } else {
  59                      $this->configuration->touch();
  60                  }
  61                  msg($this->getLang('updated'), 1);
  62              } catch (Exception $e) {
  63                  msg($this->getLang('error'), -1);
  64              }
  65              send_redirect(wl($ID, ['do' => 'admin', 'page' => 'config'], true, '&'));
  66          } else {
  67              $this->hasErrors = true;
  68              msg($this->getLang('error'), -1);
  69          }
  70      }
  71  
  72      /**
  73       * output appropriate html
  74       */
  75      public function html()
  76      {
  77          $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
  78          global $lang;
  79          global $ID;
  80  
  81          $this->setupLocale(true);
  82  
  83          echo $this->locale_xhtml('intro');
  84  
  85          echo '<div id="config__manager">';
  86  
  87          if ($this->configuration->isLocked()) {
  88              echo '<div class="info">' . $this->getLang('locked') . '</div>';
  89          }
  90  
  91          // POST to script() instead of wl($ID) so config manager still works if
  92          // rewrite config is broken. Add $ID as hidden field to remember
  93          // current ID in most cases.
  94          echo '<form id="dw__configform" action="' . script() . '" method="post">';
  95          echo '<div class="no"><input type="hidden" name="id" value="' . $ID . '" /></div>';
  96          formSecurityToken();
  97          $this->printH1('dokuwiki_settings', $this->getLang('_header_dokuwiki'));
  98  
  99          $in_fieldset = false;
 100          $first_plugin_fieldset = true;
 101          $first_template_fieldset = true;
 102          foreach ($this->configuration->getSettings() as $setting) {
 103              if ($setting instanceof SettingHidden) {
 104                  continue;
 105              } elseif ($setting instanceof SettingFieldset) {
 106                  // config setting group
 107                  if ($in_fieldset) {
 108                      echo '</table>';
 109                      echo '</div>';
 110                      echo '</fieldset>';
 111                  } else {
 112                      $in_fieldset = true;
 113                  }
 114                  if ($first_plugin_fieldset && $setting->getType() == 'plugin') {
 115                      $this->printH1('plugin_settings', $this->getLang('_header_plugin'));
 116                      $first_plugin_fieldset = false;
 117                  } elseif ($first_template_fieldset && $setting->getType() == 'template') {
 118                      $this->printH1('template_settings', $this->getLang('_header_template'));
 119                      $first_template_fieldset = false;
 120                  }
 121                  echo '<fieldset id="' . $setting->getKey() . '">';
 122                  echo '<legend>' . $setting->prompt($this) . '</legend>';
 123                  echo '<div class="table">';
 124                  echo '<table class="inline">';
 125              } else {
 126                  // config settings
 127                  [$label, $input] = $setting->html($this, $this->hasErrors);
 128  
 129                  $class = $setting->isDefault()
 130                      ? ' class="default"'
 131                      : ($setting->isProtected() ? ' class="protected"' : '');
 132                  $error = $setting->hasError()
 133                      ? ' class="value error"'
 134                      : ' class="value"';
 135                  $icon = $setting->caution()
 136                      ? '<img src="' . self::IMGDIR . $setting->caution() . '.png" ' .
 137                      'alt="' . $setting->caution() . '" title="' . $this->getLang($setting->caution()) . '" />'
 138                      : '';
 139  
 140                  echo '<tr' . $class . '>';
 141                  echo '<td class="label">';
 142                  echo '<span class="outkey">' . $setting->getPrettyKey() . '</span>';
 143                  echo $icon . $label;
 144                  echo '</td>';
 145                  echo '<td' . $error . '>' . $input . '</td>';
 146                  echo '</tr>';
 147              }
 148          }
 149  
 150          echo '</table>';
 151          echo '</div>';
 152          if ($in_fieldset) {
 153              echo '</fieldset>';
 154          }
 155  
 156          // show undefined settings list
 157          $undefined_settings = $this->configuration->getUndefined();
 158          if ($allow_debug && !empty($undefined_settings)) {
 159              /**
 160               * Callback for sorting settings
 161               *
 162               * @param Setting $a
 163               * @param Setting $b
 164               * @return int if $a is lower/equal/higher than $b
 165               */
 166              function settingNaturalComparison($a, $b)
 167              {
 168                  return strnatcmp($a->getKey(), $b->getKey());
 169              }
 170  
 171              usort($undefined_settings, 'settingNaturalComparison');
 172              $this->printH1('undefined_settings', $this->getLang('_header_undefined'));
 173              echo '<fieldset>';
 174              echo '<div class="table">';
 175              echo '<table class="inline">';
 176              foreach ($undefined_settings as $setting) {
 177                  [$label, $input] = $setting->html($this);
 178                  echo '<tr>';
 179                  echo '<td class="label">' . $label . '</td>';
 180                  echo '<td>' . $input . '</td>';
 181                  echo '</tr>';
 182              }
 183              echo '</table>';
 184              echo '</div>';
 185              echo '</fieldset>';
 186          }
 187  
 188          // finish up form
 189          echo '<p>';
 190          echo '<input type="hidden" name="do"     value="admin" />';
 191          echo '<input type="hidden" name="page"   value="config" />';
 192  
 193          if (!$this->configuration->isLocked()) {
 194              echo '<input type="hidden" name="save"   value="1" />';
 195              echo '<button type="submit" name="submit" accesskey="s">' . $lang['btn_save'] . '</button>';
 196              echo '<button type="reset">' . $lang['btn_reset'] . '</button>';
 197          }
 198  
 199          echo '</p>';
 200  
 201          echo '</form>';
 202          echo '</div>';
 203      }
 204  
 205      /**
 206       * @param bool $prompts
 207       */
 208      public function setupLocale($prompts = false)
 209      {
 210          parent::setupLocale();
 211          if (!$prompts || $this->promptsLocalized) return;
 212          $this->lang = array_merge($this->lang, $this->configuration->getLangs());
 213          $this->promptsLocalized = true;
 214      }
 215  
 216      /**
 217       * Generates a two-level table of contents for the config plugin.
 218       *
 219       * @author Ben Coburn <btcoburn@silicodon.net>
 220       *
 221       * @return array
 222       */
 223      public function getTOC()
 224      {
 225          $this->setupLocale(true);
 226  
 227          $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
 228          $toc = [];
 229          $check = false;
 230  
 231          // gather settings data into three sub arrays
 232          $labels = ['dokuwiki' => [], 'plugin' => [], 'template' => []];
 233          foreach ($this->configuration->getSettings() as $setting) {
 234              if ($setting instanceof SettingFieldset) {
 235                  $labels[$setting->getType()][] = $setting;
 236              }
 237          }
 238  
 239          // top header
 240          $title = $this->getLang('_configuration_manager');
 241          $toc[] = html_mktocitem(sectionID($title, $check), $title, 1);
 242  
 243          // main entries
 244          foreach (['dokuwiki', 'plugin', 'template'] as $section) {
 245              if (empty($labels[$section])) continue; // no entries, skip
 246  
 247              // create main header
 248              $toc[] = html_mktocitem(
 249                  $section . '_settings',
 250                  $this->getLang('_header_' . $section),
 251                  1
 252              );
 253  
 254              // create sub headers
 255              foreach ($labels[$section] as $setting) {
 256                  /** @var SettingFieldset $setting */
 257                  $name = $setting->prompt($this);
 258                  $toc[] = html_mktocitem($setting->getKey(), $name, 2);
 259              }
 260          }
 261  
 262          // undefined settings if allowed
 263          if (count($this->configuration->getUndefined()) && $allow_debug) {
 264              $toc[] = html_mktocitem('undefined_settings', $this->getLang('_header_undefined'), 1);
 265          }
 266  
 267          return $toc;
 268      }
 269  
 270      /**
 271       * @param string $id
 272       * @param string $text
 273       */
 274      protected function printH1($id, $text)
 275      {
 276          echo '<h1 id="' . $id . '">' . $text . '</h1>';
 277      }
 278  
 279      /**
 280       * Adds a translation to this plugin's language array
 281       *
 282       * Used by some settings to set up dynamic translations
 283       *
 284       * @param string $key
 285       * @param string $value
 286       */
 287      public function addLang($key, $value)
 288      {
 289          if (!$this->localised) $this->setupLocale();
 290          $this->lang[$key] = $value;
 291      }
 292  }