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