Dotclear

source: plugins/widgets/class.widgets.php @ 3827:9f0c774b0866

Revision 3827:9f0c774b0866, 9.8 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Extends opts to each type of widget setting (only 'class' is taken into account up to now)

Line 
1<?php
2/**
3 * @brief widgets, a plugin for Dotclear 2
4 *
5 * @package Dotclear
6 * @subpackage Plugins
7 *
8 * @copyright Olivier Meunier & Association Dotclear
9 * @copyright GPL-2.0-only
10 */
11
12if (!defined('DC_RC_PATH')) {return;}
13
14class dcWidgets
15{
16    private $__widgets = array();
17
18    public static function load($s)
19    {
20        $o = @unserialize(base64_decode($s));
21
22        if ($o instanceof self) {
23            return $o;
24        } else {
25            return self::loadArray($o, $GLOBALS['__widgets']);
26        }
27    }
28
29    public function store()
30    {
31        $serialized = array();
32        foreach ($this->__widgets as $pos => $w) {
33            $serialized[] = ($w->serialize($pos));
34        }
35        return base64_encode(serialize($serialized));
36    }
37
38    public function create($id, $name, $callback, $append_callback = null, $desc = '')
39    {
40        $this->__widgets[$id]                  = new dcWidget($id, $name, $callback, $desc);
41        $this->__widgets[$id]->append_callback = $append_callback;
42    }
43
44    public function append($widget)
45    {
46        if ($widget instanceof dcWidget) {
47            if (is_callable($widget->append_callback)) {
48                call_user_func($widget->append_callback, $widget);
49            }
50            $this->__widgets[] = $widget;
51        }
52    }
53
54    public function isEmpty()
55    {
56        return count($this->__widgets) == 0;
57    }
58
59    public function elements($sorted = false)
60    {
61        if ($sorted) {
62            uasort($this->__widgets, array('self', 'sort'));
63        }
64        return $this->__widgets;
65    }
66
67    public function __get($id)
68    {
69        if (!isset($this->__widgets[$id])) {
70            return;
71        }
72        return $this->__widgets[$id];
73    }
74
75    public function __wakeup()
76    {
77        foreach ($this->__widgets as $i => $w) {
78            if (!($w instanceof dcWidget)) {
79                unset($this->__widgets[$i]);
80            }
81        }
82    }
83
84    public static function loadArray($A, $widgets)
85    {
86        if (!($widgets instanceof self)) {
87            return false;
88        }
89
90        uasort($A, array('self', 'arraySort'));
91
92        $result = new self;
93        foreach ($A as $v) {
94            if ($widgets->{$v['id']} != null) {
95                $w = clone $widgets->{$v['id']};
96
97                # Settings
98                unset($v['id']);
99                unset($v['order']);
100                foreach ($v as $sid => $s) {
101                    $w->{$sid} = $s;
102                }
103
104                $result->append($w);
105            }
106        }
107
108        return $result;
109    }
110
111    private static function arraySort($a, $b)
112    {
113        if ($a['order'] == $b['order']) {
114            return 0;
115        }
116        return $a['order'] > $b['order'] ? 1 : -1;
117    }
118
119    private static function sort($a, $b)
120    {
121        $c = dcUtils::removeDiacritics(mb_strtolower($a->name()));
122        $d = dcUtils::removeDiacritics(mb_strtolower($b->name()));
123        if ($c == $d) {
124            return 0;
125        }
126        return ($c < $d) ? -1 : 1;
127    }
128}
129
130class dcWidget
131{
132    private $id;
133    private $name;
134    private $desc;
135    private $public_callback = null;
136    public $append_callback  = null;
137    private $settings        = array();
138
139    public function serialize($order)
140    {
141        $values = array();
142        foreach ($this->settings as $k => $v) {
143            $values[$k] = $v['value'];
144        }
145
146        $values['id']    = $this->id;
147        $values['order'] = $order;
148        return $values;
149    }
150
151    public function __construct($id, $name, $callback, $desc = '')
152    {
153        $this->public_callback = $callback;
154        $this->id              = $id;
155        $this->name            = $name;
156        $this->desc            = $desc;
157    }
158
159    public function id()
160    {
161        return $this->id;
162    }
163
164    public function name()
165    {
166        return $this->name;
167    }
168
169    public function desc()
170    {
171        return $this->desc;
172    }
173
174    public function getCallback()
175    {
176        return $this->public_callback;
177    }
178
179    public function call($i = 0)
180    {
181        if (is_callable($this->public_callback)) {
182            return call_user_func($this->public_callback, $this, $i);
183        }
184        return '<p>Callback not found for widget ' . $this->id . '</p>';
185    }
186
187    /* Widget rendering tool
188    --------------------------------------------------- */
189    public function renderDiv($content_only, $class, $attr, $content)
190    {
191        if ($content_only) {
192            return $content;
193        }
194        $ret = '<div class="widget' . ($class ? ' ' . html::escapeHTML($class) : '') . '"' . ($attr ? ' ' . $attr : '') . '>' . "\n";
195        $ret .= $content . "\n";
196        $ret .= '</div>' . "\n";
197
198        return $ret;
199    }
200
201    public function renderTitle($title)
202    {
203        global $core;
204
205        if (!$title) {
206            return '';
207        }
208
209        $wtscheme = $core->themes->moduleInfo($core->blog->settings->system->theme, 'widgettitleformat');
210        if (empty($wtscheme)) {
211            $tplset = $core->themes->moduleInfo($core->blog->settings->system->theme, 'tplset');
212            if (empty($tplset) || $tplset == DC_DEFAULT_TPLSET) {
213                // Use H2 for mustek based themes
214                $wtscheme = '<h2>%s</h2>';
215            } else {
216                // Use H3 for currywurst based themes
217                $wtscheme = '<h3>%s</h3>';
218            }
219        }
220        $ret = sprintf($wtscheme, $title);
221
222        return $ret;
223    }
224
225    public function renderSubtitle($title, $render = true)
226    {
227        global $core;
228
229        if (!$title && $render) {
230            return '';
231        }
232
233        $wtscheme = $core->themes->moduleInfo($core->blog->settings->system->theme, 'widgetsubtitleformat');
234        if (empty($wtscheme)) {
235            $tplset = $core->themes->moduleInfo($core->blog->settings->system->theme, 'tplset');
236            if (empty($tplset) || $tplset == DC_DEFAULT_TPLSET) {
237                // Use H2 for mustek based themes
238                $wtscheme = '<h3>%s</h3>';
239            } else {
240                // Use H3 for currywurst based themes
241                $wtscheme = '<h4>%s</h4>';
242            }
243        }
244        if (!$render) {
245            return $wtscheme;
246        }
247
248        $ret = sprintf($wtscheme, $title);
249        return $ret;
250    }
251
252    /* Widget settings
253    --------------------------------------------------- */
254    public function __get($n)
255    {
256        if (isset($this->settings[$n])) {
257            return $this->settings[$n]['value'];
258        }
259        return;
260    }
261
262    public function __set($n, $v)
263    {
264        if (isset($this->settings[$n])) {
265            $this->settings[$n]['value'] = $v;
266        }
267    }
268
269    public function setting($name, $title, $value, $type = 'text')
270    {
271        if ($type == 'combo' || $type == 'radio') {
272            $options = @func_get_arg(4);
273            if (!is_array($options)) {
274                return false;
275            }
276            // If any, the 5th argument should be an array (key → value) of opts
277            $opts = @func_get_arg(5);
278        } else {
279            // If any, the 4th argument should be an array (key → value) of opts
280            $opts = @func_get_arg(4);
281        }
282
283        $this->settings[$name] = array(
284            'title' => $title,
285            'type'  => $type,
286            'value' => $value
287        );
288
289        if (isset($options)) {
290            $this->settings[$name]['options'] = $options;
291        }
292        if (isset($opt)) {
293            $this->settings[$name]['opts'] = $opts;
294        }
295    }
296
297    public function settings()
298    {
299        return $this->settings;
300    }
301
302    public function formSettings($pr = '', &$i = 0)
303    {
304        $res = '';
305        foreach ($this->settings as $id => $s) {
306            $res .= $this->formSetting($id, $s, $pr, $i);
307            $i++;
308        }
309
310        return $res;
311    }
312
313    public function formSetting($id, $s, $pr = '', &$i = 0)
314    {
315        $res   = '';
316        $wfid  = "wf-" . $i;
317        $iname = $pr ? $pr . '[' . $id . ']' : $id;
318        $class = (isset($s['opts']) && isset($s['opts']['class']) ? ' ' . $s['opts']['class'] : '');
319        switch ($s['type']) {
320            case 'text':
321                $res .=
322                '<p><label for="' . $wfid . '">' . $s['title'] . '</label> ' .
323                form::field(array($iname, $wfid), 20, 255, html::escapeHTML($s['value']), 'maximal' . $class) .
324                    '</p>';
325                break;
326            case 'textarea':
327                $res .=
328                '<p><label for="' . $wfid . '">' . $s['title'] . '</label> ' .
329                form::textarea(array($iname, $wfid), 30, 8, html::escapeHTML($s['value']), 'maximal' . $class) .
330                    '</p>';
331                break;
332            case 'check':
333                $res .=
334                '<p>' . form::hidden(array($iname), '0') .
335                '<label class="classic" for="' . $wfid . '">' .
336                form::checkbox(array($iname, $wfid), '1', $s['value'], $class) . ' ' . $s['title'] .
337                    '</label></p>';
338                break;
339            case 'radio':
340                $res .= '<p>' . ($s['title'] ? '<label class="classic">' . $s['title'] . '</label><br/>' : '');
341                if (!empty($s['options'])) {
342                    foreach ($s['options'] as $k => $v) {
343                        $res .= $k > 0 ? '<br/>' : '';
344                        $res .=
345                        '<label class="classic" for="' . $wfid . '-' . $k . '">' .
346                        form::radio(array($iname, $wfid . '-' . $k), $v[1], $s['value'] == $v[1], $class) . ' ' . $v[0] .
347                            '</label>';
348                    }
349                }
350                $res .= '</p>';
351                break;
352            case 'combo':
353                $res .=
354                '<p><label for="' . $wfid . '">' . $s['title'] . '</label> ' .
355                form::combo(array($iname, $wfid), $s['options'], $s['value'], $class) .
356                    '</p>';
357                break;
358        }
359        return $res;
360    }
361}
Note: See TracBrowser for help on using the repository browser.

Sites map