[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/Extension/ -> PluginTrait.php (source)

   1  <?php
   2  
   3  namespace dokuwiki\Extension;
   4  
   5  use dokuwiki\Logger;
   6  
   7  /**
   8   * Provides standard DokuWiki plugin behaviour
   9   */
  10  trait PluginTrait
  11  {
  12      protected $localised = false;        // set to true by setupLocale() after loading language dependent strings
  13      protected $lang = [];           // array to hold language dependent strings, best accessed via ->getLang()
  14      protected $configloaded = false;     // set to true by loadConfig() after loading plugin configuration variables
  15      protected $conf = [];           // array to hold plugin settings, best accessed via ->getConf()
  16  
  17      /**
  18       * @see PluginInterface::getInfo()
  19       */
  20      public function getInfo()
  21      {
  22          $class = get_class($this);
  23          $parts = sexplode('_', $class, 3);
  24          $ext = $parts[2];
  25  
  26          if (empty($ext)) {
  27              throw new \RuntimeException('Class does not follow the plugin naming convention');
  28          }
  29  
  30          // class like action_plugin_myplugin_ajax belongs to plugin 'myplugin'
  31          $ext = strtok($ext, '_');
  32  
  33          $base = [
  34              'base' => $ext,
  35              'author' => 'Unknown',
  36              'email' => 'unknown@example.com',
  37              'date' => '0000-00-00',
  38              'name' => $ext . ' plugin',
  39              'desc' => 'Unknown purpose - bad plugin.info.txt',
  40              'url' => 'https://www.dokuwiki.org/plugins/' . $ext,
  41          ];
  42  
  43          $file = DOKU_PLUGIN . '/' . $ext . '/plugin.info.txt';
  44          if (file_exists($file)) {
  45              $raw = confToHash($file);
  46  
  47              // check if all required fields are present
  48              $msg = 'Extension %s does not provide a valid %s in %s';
  49              foreach (array_keys($base) as $line) {
  50                  if (empty($raw[$line])) Logger::error(sprintf($msg, $ext, $line, $file));
  51              }
  52  
  53              return array_merge($base, $raw);
  54          }
  55  
  56          Logger::error(sprintf('Extension %s does not provide a plugin.info.txt in %s', $ext, $file));
  57          return $base;
  58      }
  59  
  60      /**
  61       * @see PluginInterface::isSingleton()
  62       */
  63      public function isSingleton()
  64      {
  65          return true;
  66      }
  67  
  68      /**
  69       * @see PluginInterface::loadHelper()
  70       */
  71      public function loadHelper($name, $msg = true)
  72      {
  73          $obj = plugin_load('helper', $name);
  74          if (is_null($obj) && $msg) msg("Helper plugin $name is not available or invalid.", -1);
  75          return $obj;
  76      }
  77  
  78      // region introspection methods
  79  
  80      /**
  81       * @see PluginInterface::getPluginType()
  82       */
  83      public function getPluginType()
  84      {
  85          [$t] = explode('_', get_class($this), 2);
  86          return $t;
  87      }
  88  
  89      /**
  90       * @see PluginInterface::getPluginName()
  91       */
  92      public function getPluginName()
  93      {
  94          [/* t */, /* p */, $n] = sexplode('_', get_class($this), 4, '');
  95          return $n;
  96      }
  97  
  98      /**
  99       * @see PluginInterface::getPluginComponent()
 100       */
 101      public function getPluginComponent()
 102      {
 103          [/* t */, /* p */, /* n */, $c] = sexplode('_', get_class($this), 4, '');
 104          return $c;
 105      }
 106  
 107      // endregion
 108      // region localization methods
 109  
 110      /**
 111       * @see PluginInterface::getLang()
 112       */
 113      public function getLang($id)
 114      {
 115          if (!$this->localised) $this->setupLocale();
 116  
 117          return ($this->lang[$id] ?? '');
 118      }
 119  
 120      /**
 121       * @see PluginInterface::locale_xhtml()
 122       */
 123      public function locale_xhtml($id)
 124      {
 125          return p_cached_output($this->localFN($id));
 126      }
 127  
 128      /**
 129       * @see PluginInterface::localFN()
 130       */
 131      public function localFN($id, $ext = 'txt')
 132      {
 133          global $conf;
 134          $plugin = $this->getPluginName();
 135          $file = DOKU_CONF . 'plugin_lang/' . $plugin . '/' . $conf['lang'] . '/' . $id . '.' . $ext;
 136          if (!file_exists($file)) {
 137              $file = DOKU_PLUGIN . $plugin . '/lang/' . $conf['lang'] . '/' . $id . '.' . $ext;
 138              if (!file_exists($file)) {
 139                  //fall back to english
 140                  $file = DOKU_PLUGIN . $plugin . '/lang/en/' . $id . '.' . $ext;
 141              }
 142          }
 143          return $file;
 144      }
 145  
 146      /**
 147       * @see PluginInterface::setupLocale()
 148       */
 149      public function setupLocale()
 150      {
 151          if ($this->localised) return;
 152  
 153          global $conf, $config_cascade; // definitely don't invoke "global $lang"
 154          $path = DOKU_PLUGIN . $this->getPluginName() . '/lang/';
 155  
 156          $lang = [];
 157  
 158          // don't include once, in case several plugin components require the same language file
 159          @include($path . 'en/lang.php');
 160          foreach ($config_cascade['lang']['plugin'] as $config_file) {
 161              if (file_exists($config_file . $this->getPluginName() . '/en/lang.php')) {
 162                  include($config_file . $this->getPluginName() . '/en/lang.php');
 163              }
 164          }
 165  
 166          if ($conf['lang'] != 'en') {
 167              @include($path . $conf['lang'] . '/lang.php');
 168              foreach ($config_cascade['lang']['plugin'] as $config_file) {
 169                  if (file_exists($config_file . $this->getPluginName() . '/' . $conf['lang'] . '/lang.php')) {
 170                      include($config_file . $this->getPluginName() . '/' . $conf['lang'] . '/lang.php');
 171                  }
 172              }
 173          }
 174  
 175          $this->lang = $lang;
 176          $this->localised = true;
 177      }
 178  
 179      // endregion
 180      // region configuration methods
 181  
 182      /**
 183       * @see PluginInterface::getConf()
 184       */
 185      public function getConf($setting, $notset = false)
 186      {
 187  
 188          if (!$this->configloaded) {
 189              $this->loadConfig();
 190          }
 191  
 192          if (isset($this->conf[$setting])) {
 193              return $this->conf[$setting];
 194          } else {
 195              return $notset;
 196          }
 197      }
 198  
 199      /**
 200       * @see PluginInterface::loadConfig()
 201       */
 202      public function loadConfig()
 203      {
 204          global $conf;
 205  
 206          $defaults = $this->readDefaultSettings();
 207          $plugin = $this->getPluginName();
 208  
 209          foreach ($defaults as $key => $value) {
 210              if (isset($conf['plugin'][$plugin][$key])) continue;
 211              $conf['plugin'][$plugin][$key] = $value;
 212          }
 213  
 214          $this->configloaded = true;
 215          $this->conf =& $conf['plugin'][$plugin];
 216      }
 217  
 218      /**
 219       * read the plugin's default configuration settings from conf/default.php
 220       * this function is automatically called through getConf()
 221       *
 222       * @return    array    setting => value
 223       */
 224      protected function readDefaultSettings()
 225      {
 226  
 227          $path = DOKU_PLUGIN . $this->getPluginName() . '/conf/';
 228          $conf = [];
 229  
 230          if (file_exists($path . 'default.php')) {
 231              include($path . 'default.php');
 232          }
 233  
 234          return $conf;
 235      }
 236  
 237      // endregion
 238      // region output methods
 239  
 240      /**
 241       * @see PluginInterface::email()
 242       */
 243      public function email($email, $name = '', $class = '', $more = '')
 244      {
 245          if (!$email) return $name;
 246          $email = obfuscate($email);
 247          if (!$name) $name = $email;
 248          $class = "class='" . ($class ?: 'mail') . "'";
 249          return "<a href='mailto:$email' $class title='$email' $more>$name</a>";
 250      }
 251  
 252      /**
 253       * @see PluginInterface::external_link()
 254       */
 255      public function external_link($link, $title = '', $class = '', $target = '', $more = '')
 256      {
 257          global $conf;
 258  
 259          $link = htmlentities($link);
 260          if (!$title) $title = $link;
 261          if (!$target) $target = $conf['target']['extern'];
 262          if ($conf['relnofollow']) $more .= ' rel="nofollow"';
 263  
 264          if ($class) $class = " class='$class'";
 265          if ($target) $target = " target='$target'";
 266          if ($more) $more = " " . trim($more);
 267  
 268          return "<a href='$link'$class$target$more>$title</a>";
 269      }
 270  
 271      /**
 272       * @see PluginInterface::render_text()
 273       */
 274      public function render_text($text, $format = 'xhtml')
 275      {
 276          return p_render($format, p_get_instructions($text), $info);
 277      }
 278  
 279      // endregion
 280  }