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