Dotclear

source: plugins/simpleMenu/index.php @ 3902:861a3d1a15f3

Revision 3902:861a3d1a15f3, 24.9 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Use numeric fields (with min/max) for sortering items (categories, …), fix ordering of simple menu items when drag'n'drop is disabled

Line 
1<?php
2/**
3 * @brief simpleMenu, 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_CONTEXT_ADMIN')) {return;}
13
14dcPage::check('admin');
15
16$page_title = __('Simple menu');
17
18# Url de base
19$p_url = $core->adminurl->get('admin.plugin.simpleMenu');
20
21# Url du blog
22$blog_url = html::stripHostURL($core->blog->url);
23
24# Liste des catégories
25$categories_label = [];
26$rs               = $core->blog->getCategories(['post_type' => 'post']);
27$categories_combo = dcAdminCombos::getCategoriesCombo($rs, false, true);
28$rs->moveStart();
29while ($rs->fetch()) {
30    $categories_label[$rs->cat_url] = html::escapeHTML($rs->cat_title);
31}
32
33# Liste des langues utilisées
34$langs_combo = dcAdminCombos::getLangscombo(
35    $core->blog->getLangs(['order' => 'asc'])
36);
37
38# Liste des mois d'archive
39$rs           = $core->blog->getDates(['type' => 'month']);
40$months_combo = array_merge(
41    [__('All months') => '-'],
42    dcAdmincombos::getDatesCombo($rs)
43);
44
45$first_year = $last_year = 0;
46while ($rs->fetch()) {
47    if (($first_year == 0) || ($rs->year() < $first_year)) {
48        $first_year = $rs->year();
49    }
50
51    if (($last_year == 0) || ($rs->year() > $last_year)) {
52        $last_year = $rs->year();
53    }
54
55}
56unset($rs);
57
58# Liste des pages -- Doit être pris en charge plus tard par le plugin ?
59$pages_combo = [];
60try {
61    $rs = $core->blog->getPosts(['post_type' => 'page']);
62    while ($rs->fetch()) {
63        $pages_combo[$rs->post_title] = $rs->getURL();
64    }
65    unset($rs);
66} catch (Exception $e) {}
67
68# Liste des tags -- Doit être pris en charge plus tard par le plugin ?
69$tags_combo = [];
70try {
71    $rs                         = $core->meta->getMetadata(['meta_type' => 'tag']);
72    $tags_combo[__('All tags')] = '-';
73    while ($rs->fetch()) {
74        $tags_combo[$rs->meta_id] = $rs->meta_id;
75    }
76    unset($rs);
77} catch (Exception $e) {}
78
79# Liste des types d'item de menu
80$items         = new ArrayObject();
81$items['home'] = new ArrayObject([__('Home'), false]);
82
83if (count($langs_combo) > 1) {
84    $items['lang'] = new ArrayObject([__('Language'), true]);
85}
86if (count($categories_combo)) {
87    $items['category'] = new ArrayObject([__('Category'), true]);
88}
89if (count($months_combo) > 1) {
90    $items['archive'] = new ArrayObject([__('Archive'), true]);
91}
92if ($core->plugins->moduleExists('pages')) {
93    if (count($pages_combo)) {
94        $items['pages'] = new ArrayObject([__('Page'), true]);
95    }
96
97}
98if ($core->plugins->moduleExists('tags')) {
99    if (count($tags_combo) > 1) {
100        $items['tags'] = new ArrayObject([__('Tags'), true]);
101    }
102
103}
104
105# --BEHAVIOR-- adminSimpleMenuAddType
106# Should add an item to $items[<id>] as an [<label>,<optional step (true or false)>]
107$core->callBehavior('adminSimpleMenuAddType', $items);
108
109$items['special'] = new ArrayObject([__('User defined'), false]);
110
111$items_combo = [];
112foreach ($items as $k => $v) {
113    $items_combo[$v[0]] = $k;
114}
115
116# Lecture menu existant
117$menu = $core->blog->settings->system->get('simpleMenu');
118if (!is_array($menu)) {
119    $menu = [];
120}
121
122# Récupération état d'activation du menu
123$menu_active = (boolean) $core->blog->settings->system->simpleMenu_active;
124
125// Saving new configuration
126if (!empty($_POST['saveconfig'])) {
127    try
128    {
129        $menu_active = (empty($_POST['active'])) ? false : true;
130        $core->blog->settings->system->put('simpleMenu_active', $menu_active, 'boolean');
131        $core->blog->triggerBlog();
132
133        // All done successfully, return to menu items list
134        dcPage::addSuccessNotice(__('Configuration successfully updated.'));
135        http::redirect($p_url);
136    } catch (Exception $e) {
137        $core->error->add($e->getMessage());
138    }
139} else {
140    # Récupération paramètres postés
141    $item_type        = isset($_POST['item_type']) ? $_POST['item_type'] : '';
142    $item_select      = isset($_POST['item_select']) ? $_POST['item_select'] : '';
143    $item_label       = isset($_POST['item_label']) ? $_POST['item_label'] : '';
144    $item_descr       = isset($_POST['item_descr']) ? $_POST['item_descr'] : '';
145    $item_url         = isset($_POST['item_url']) ? $_POST['item_url'] : '';
146    $item_targetBlank = isset($_POST['item_targetBlank']) ? (empty($_POST['item_targetBlank'])) ? false : true : false;
147    # Traitement
148    $step = (!empty($_GET['add']) ? (integer) $_GET['add'] : 0);
149    if (($step > 4) || ($step < 0)) {
150        $step = 0;
151    }
152
153    if ($step) {
154
155        # Récupération libellés des choix
156        $item_type_label = isset($items[$item_type]) ? $items[$item_type][0] : '';
157
158        switch ($step) {
159            case 1:
160                // First step, menu item type to be selected
161                $item_type = $item_select = '';
162                break;
163            case 2:
164                if ($items[$item_type][1]) {
165                    // Second step (optional), menu item sub-type to be selected
166                    $item_select = '';
167                    break;
168                }
169            case 3:
170                // Third step, menu item attributes to be changed or completed if necessary
171                $item_select_label = '';
172                $item_label        = __('Label');
173                $item_descr        = __('Description');
174                $item_url          = $blog_url;
175                switch ($item_type) {
176                    case 'home':
177                        $item_label = __('Home');
178                        $item_descr = __('Recent posts');
179                        break;
180                    case 'lang':
181                        $item_select_label = array_search($item_select, $langs_combo);
182                        $item_label        = $item_select_label;
183                        $item_descr        = sprintf(__('Switch to %s language'), $item_select_label);
184                        $item_url .= $core->url->getURLFor('lang', $item_select);
185                        break;
186                    case 'category':
187                        $item_select_label = $categories_label[$item_select];
188                        $item_label        = $item_select_label;
189                        $item_descr        = __('Recent Posts from this category');
190                        $item_url .= $core->url->getURLFor('category', $item_select);
191                        break;
192                    case 'archive':
193                        $item_select_label = array_search($item_select, $months_combo);
194                        if ($item_select == '-') {
195                            $item_label = __('Archives');
196                            $item_descr = $first_year . ($first_year != $last_year ? ' - ' . $last_year : '');
197                            $item_url .= $core->url->getURLFor('archive');
198                        } else {
199                            $item_label = $item_select_label;
200                            $item_descr = sprintf(__('Posts from %s'), $item_select_label);
201                            $item_url .= $core->url->getURLFor('archive', substr($item_select, 0, 4) . '/' . substr($item_select, -2));
202                        }
203                        break;
204                    case 'pages':
205                        $item_select_label = array_search($item_select, $pages_combo);
206                        $item_label        = $item_select_label;
207                        $item_descr        = '';
208                        $item_url          = html::stripHostURL($item_select);
209                        break;
210                    case 'tags':
211                        $item_select_label = array_search($item_select, $tags_combo);
212                        if ($item_select == '-') {
213                            $item_label = __('All tags');
214                            $item_descr = '';
215                            $item_url .= $core->url->getURLFor('tags');
216                        } else {
217                            $item_label = $item_select_label;
218                            $item_descr = sprintf(__('Recent posts for %s tag'), $item_select_label);
219                            $item_url .= $core->url->getURLFor('tag', $item_select);
220                        }
221                        break;
222                    case 'special':
223                        break;
224                    default:
225                        # --BEHAVIOR-- adminSimpleMenuBeforeEdit
226                        # Should modify if necessary $item_label, $item_descr and $item_url
227                        # Should set if necessary $item_select_label (displayed on further admin step only)
228                        $core->callBehavior('adminSimpleMenuBeforeEdit', $item_type, $item_select,
229                            [ & $item_label, &$item_descr, &$item_url, &$item_select_label]);
230                        break;
231                }
232                break;
233            case 4:
234                // Fourth step, menu item to be added
235                try {
236                    if (($item_label != '') && ($item_url != '')) {
237                        // Add new item menu in menu array
238                        $menu[] = [
239                            'label'       => $item_label,
240                            'descr'       => $item_descr,
241                            'url'         => $item_url,
242                            'targetBlank' => $item_targetBlank
243                        ];
244
245                        // Save menu in blog settings
246                        $core->blog->settings->system->put('simpleMenu', $menu);
247                        $core->blog->triggerBlog();
248
249                        // All done successfully, return to menu items list
250                        dcPage::addSuccessNotice(__('Menu item has been successfully added.'));
251                        http::redirect($p_url);
252                    } else {
253                        $step              = 3;
254                        $item_select_label = $item_label;
255                        dcPage::addErrorNotice(__('Label and URL of menu item are mandatory.'));
256                    }
257                } catch (Exception $e) {
258                    $core->error->add($e->getMessage());
259                }
260                break;
261        }
262    } else {
263
264        # Remove selected menu items
265        if (!empty($_POST['removeaction'])) {
266            try {
267                if (!empty($_POST['items_selected'])) {
268                    foreach ($_POST['items_selected'] as $k => $v) {
269                        $menu[$v]['label'] = '';
270                    }
271                    $newmenu = [];
272                    foreach ($menu as $k => $v) {
273                        if ($v['label']) {
274                            $newmenu[] = [
275                                'label'       => $v['label'],
276                                'descr'       => $v['descr'],
277                                'url'         => $v['url'],
278                                'targetBlank' => $v['targetBlank']
279                            ];
280                        }
281                    }
282                    $menu = $newmenu;
283                    // Save menu in blog settings
284                    $core->blog->settings->system->put('simpleMenu', $menu);
285                    $core->blog->triggerBlog();
286
287                    // All done successfully, return to menu items list
288                    dcPage::addSuccessNotice(__('Menu items have been successfully removed.'));
289                    http::redirect($p_url);
290                } else {
291                    throw new Exception(__('No menu items selected.'));
292                }
293            } catch (Exception $e) {
294                $core->error->add($e->getMessage());
295            }
296        }
297
298        # Update menu items
299        if (!empty($_POST['updateaction'])) {
300            try {
301                foreach ($_POST['items_label'] as $k => $v) {
302                    if (!$v) {
303                        throw new Exception(__('Label is mandatory.'));
304                    }
305
306                }
307                foreach ($_POST['items_url'] as $k => $v) {
308                    if (!$v) {
309                        throw new Exception(__('URL is mandatory.'));
310                    }
311
312                }
313                $newmenu = [];
314                for ($i = 0; $i < count($_POST['items_label']); $i++) {
315                    $newmenu[] = [
316                        'label'       => $_POST['items_label'][$i],
317                        'descr'       => $_POST['items_descr'][$i],
318                        'url'         => $_POST['items_url'][$i],
319                        'targetBlank' => (empty($_POST['items_targetBlank' . $i])) ? false : true
320                    ];
321                }
322                $menu = $newmenu;
323
324                $core->auth->user_prefs->addWorkspace('accessibility');
325                if ($core->auth->user_prefs->accessibility->nodragdrop) {
326                    # Order menu items
327                    $order = [];
328                    if (empty($_POST['im_order']) && !empty($_POST['order'])) {
329                        $order = $_POST['order'];
330                        asort($order);
331                        $order = array_keys($order);
332                    } elseif (!empty($_POST['im_order'])) {
333                        $order = $_POST['im_order'];
334                        if (substr($order, -1) == ',') {
335                            $order = substr($order, 0, strlen($order) - 1);
336                        }
337                        $order = explode(',', $order);
338                    }
339                    if (!empty($order)) {
340                        $newmenu = [];
341                        foreach ($order as $i => $k) {
342                            $newmenu[] = [
343                                'label' => $menu[$k]['label'],
344                                'descr' => $menu[$k]['descr'],
345                                'url'   => $menu[$k]['url']];
346                        }
347                        $menu = $newmenu;
348                    }
349                }
350
351                // Save menu in blog settings
352                $core->blog->settings->system->put('simpleMenu', $menu);
353                $core->blog->triggerBlog();
354
355                // All done successfully, return to menu items list
356                dcPage::addSuccessNotice(__('Menu items have been successfully updated.'));
357                http::redirect($p_url);
358            } catch (Exception $e) {
359                $core->error->add($e->getMessage());
360            }
361        }
362    }
363}
364
365# Display
366?>
367
368<html>
369<head>
370    <title><?php echo $page_title; ?></title>
371    <?php
372$core->auth->user_prefs->addWorkspace('accessibility');
373if (!$core->auth->user_prefs->accessibility->nodragdrop) {
374    echo
375    dcPage::jsLoad('js/jquery/jquery-ui.custom.js') .
376    dcPage::jsLoad('js/jquery/jquery.ui.touch-punch.js') .
377    dcPage::jsLoad(dcPage::getPF('simpleMenu/js/simplemenu.js'));
378}
379echo dcPage::jsConfirmClose('settings', 'menuitemsappend', 'additem', 'menuitems');
380?>
381</head>
382
383<body>
384
385<?php
386
387if ($step) {
388    switch ($step) {
389        case 1:
390            $step_label = __('Step #1');
391            break;
392        case 2:
393            if ($items[$item_type][1]) {
394                $step_label = __('Step #2');
395                break;
396            }
397        case 3:
398            if ($items[$item_type][1]) {
399                $step_label = __('Step #3');
400            } else {
401                $step_label = __('Step #2');
402            }
403            break;
404    }
405    echo dcPage::breadcrumb(
406        [
407            html::escapeHTML($core->blog->name) => '',
408            $page_title                         => $p_url,
409            __('Add item')                      => '',
410            $step_label                         => ''
411        ],
412        [
413            'hl_pos' => -2]
414    ) .
415    dcPage::notices();
416} else {
417    echo dcPage::breadcrumb(
418        [
419            html::escapeHTML($core->blog->name) => '',
420            $page_title                         => ''
421        ]) .
422    dcPage::notices();
423}
424
425if ($step) {
426    // Formulaire d'ajout d'un item
427    switch ($step) {
428        case 1:
429            // Selection du type d'item
430            echo '<form id="additem" action="' . $p_url . '&amp;add=2" method="post">';
431            echo '<fieldset><legend>' . __('Select type') . '</legend>';
432            echo '<p class="field"><label for="item_type" class="classic">' . __('Type of item menu:') . '</label>' . form::combo('item_type', $items_combo) . '</p>';
433            echo '<p>' . $core->formNonce() . '<input type="submit" name="appendaction" value="' . __('Continue...') . '" />' . '</p>';
434            echo '</fieldset>';
435            echo '</form>';
436            break;
437        case 2:
438            if ($items[$item_type][1]) {
439                // Choix à faire
440                echo '<form id="additem" action="' . $p_url . '&amp;add=3" method="post">';
441                echo '<fieldset><legend>' . $item_type_label . '</legend>';
442                switch ($item_type) {
443                    case 'lang':
444                        echo '<p class="field"><label for="item_select" class="classic">' . __('Select language:') . '</label>' .
445                        form::combo('item_select', $langs_combo);
446                        break;
447                    case 'category':
448                        echo '<p class="field"><label for="item_select" class="classic">' . __('Select category:') . '</label>' .
449                        form::combo('item_select', $categories_combo);
450                        break;
451                    case 'archive':
452                        echo '<p class="field"><label for="item_select" class="classic">' . __('Select month (if necessary):') . '</label>' .
453                        form::combo('item_select', $months_combo);
454                        break;
455                    case 'pages':
456                        echo '<p class="field"><label for="item_select" class="classic">' . __('Select page:') . '</label>' .
457                        form::combo('item_select', $pages_combo);
458                        break;
459                    case 'tags':
460                        echo '<p class="field"><label for="item_select" class="classic">' . __('Select tag (if necessary):') . '</label>' .
461                        form::combo('item_select', $tags_combo);
462                        break;
463                    default:
464                        echo
465                        # --BEHAVIOR-- adminSimpleMenuSelect
466                        # Optional step once $item_type known : should provide a field using 'item_select' as id
467                        $core->callBehavior('adminSimpleMenuSelect', $item_type, 'item_select');
468                }
469                echo form::hidden('item_type', $item_type);
470                echo '<p>' . $core->formNonce() . '<input type="submit" name="appendaction" value="' . __('Continue...') . '" /></p>';
471                echo '</fieldset>';
472                echo '</form>';
473                break;
474            }
475        case 3:
476            // Libellé et description
477            echo '<form id="additem" action="' . $p_url . '&amp;add=4" method="post">';
478            echo '<fieldset><legend>' . $item_type_label . ($item_select_label != '' ? ' (' . $item_select_label . ')' : '') . '</legend>';
479            echo '<p class="field"><label for="item_label" class="classic required"><abbr title="' . __('Required field') . '">*</abbr> ' .
480            __('Label of item menu:') . '</label>' .
481            form::field('item_label', 20, 255, [
482                'default'    => $item_label,
483                'extra_html' => 'required placeholder="' . __('Label') . '" lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
484            ]) .
485                '</p>';
486            echo '<p class="field"><label for="item_descr" class="classic">' .
487            __('Description of item menu:') . '</label>' . form::field('item_descr', 30, 255,
488                [
489                    'default'    => $item_descr,
490                    'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
491                ]) . '</p>';
492            echo '<p class="field"><label for="item_url" class="classic required"><abbr title="' . __('Required field') . '">*</abbr> ' .
493            __('URL of item menu:') . '</label>' .
494            form::field('item_url', 40, 255, [
495                'default'    => $item_url,
496                'extra_html' => 'required placeholder="' . __('URL') . '"'
497            ]) .
498                '</p>';
499            echo form::hidden('item_type', $item_type) . form::hidden('item_select', $item_select);
500            echo '<p class="field"><label for="item_descr" class="classic">' .
501            __('Open URL on a new tab') . ':</label>' . form::checkbox('item_targetBlank', 'blank') . '</p>';
502            echo '<p>' . $core->formNonce() . '<input type="submit" name="appendaction" value="' . __('Add this item') . '" /></p>';
503            echo '</fieldset>';
504            echo '</form>';
505            break;
506    }
507}
508
509// Formulaire d'activation
510if (!$step) {
511    echo '<form id="settings" action="' . $p_url . '" method="post">' .
512    '<p>' . form::checkbox('active', 1, $menu_active) .
513    '<label class="classic" for="active">' . __('Enable simple menu for this blog') . '</label>' . '</p>' .
514    '<p>' . $core->formNonce() . '<input type="submit" name="saveconfig" value="' . __('Save configuration') . '" />' . '</p>' .
515        '</form>';
516}
517
518// Liste des items
519if (!$step) {
520    echo '<form id="menuitemsappend" action="' . $p_url . '&amp;add=1" method="post">';
521    echo '<p class="top-add">' . $core->formNonce() . '<input class="button add" type="submit" name="appendaction" value="' . __('Add an item') . '" /></p>';
522    echo '</form>';
523}
524
525if (count($menu)) {
526    if (!$step) {
527        echo '<form id="menuitems" action="' . $p_url . '" method="post">';
528    }
529    // Entête table
530    echo
531    '<div class="table-outer">' .
532    '<table class="dragable">' .
533    '<caption>' . __('Menu items list') . '</caption>' .
534        '<thead>' .
535        '<tr>';
536    if (!$step) {
537        echo '<th scope="col"></th>';
538        echo '<th scope="col"></th>';
539    }
540    echo
541    '<th scope="col">' . __('Label') . '</th>' .
542    '<th scope="col">' . __('Description') . '</th>' .
543    '<th scope="col">' . __('URL') . '</th>' .
544    '<th scope="col">' . __('Open URL on a new tab') . '</th>' .
545        '</tr>' .
546        '</thead>' .
547        '<tbody' . (!$step ? ' id="menuitemslist"' : '') . '>';
548    $count = 0;
549    foreach ($menu as $i => $m) {
550        echo '<tr class="line" id="l_' . $i . '">';
551
552        //because targetBlank can not exists. This value has been added after this plugin creation.
553        if ((isset($m['targetBlank'])) && ($m['targetBlank'])) {
554            $targetBlank    = true;
555            $targetBlankStr = 'X';
556        } else {
557            $targetBlank    = false;
558            $targetBlankStr = '';
559        }
560
561        if (!$step) {
562            $count++;
563            echo '<td class="handle minimal">' .
564            form::number(['order[' . $i . ']'], [
565                'min'        => 1,
566                'max'        => count($menu),
567                'default'    => $count,
568                'class'      => 'position',
569                'extra_html' => 'title="' . sprintf(__('position of %s'), html::escapeHTML(__($m['label']))) . '"'
570            ]) .
571            form::hidden(['dynorder[]', 'dynorder-' . $i], $i) . '</td>';
572            echo '<td class="minimal">' . form::checkbox(['items_selected[]', 'ims-' . $i], $i) . '</td>';
573            echo '<td class="nowrap" scope="row">' . form::field(['items_label[]', 'iml-' . $i], '', 255,
574                [
575                    'default'    => html::escapeHTML(__($m['label'])),
576                    'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
577                ]) . '</td>';
578            echo '<td class="nowrap">' . form::field(['items_descr[]', 'imd-' . $i], '30', 255,
579                [
580                    'default'    => html::escapeHTML(__($m['descr'])),
581                    'extra_html' => 'lang="' . $core->auth->getInfo('user_lang') . '" spellcheck="true"'
582                ]) . '</td>';
583            echo '<td class="nowrap">' . form::field(['items_url[]', 'imu-' . $i], '30', 255, html::escapeHTML($m['url'])) . '</td>';
584            echo '<td class="nowrap">' . form::checkbox('items_targetBlank' . $i, 'blank', $targetBlank) . '</td>';
585        } else {
586            echo '<td class="nowrap" scope="row">' . html::escapeHTML(__($m['label'])) . '</td>';
587            echo '<td class="nowrap">' . html::escapeHTML(__($m['descr'])) . '</td>';
588            echo '<td class="nowrap">' . html::escapeHTML($m['url']) . '</td>';
589            echo '<td class="nowrap">' . $targetBlankStr . '</td>';
590
591        }
592        echo '</tr>';
593    }
594    echo '</tbody>' .
595        '</table></div>';
596    if (!$step) {
597        echo '<div class="two-cols">';
598        echo '<p class="col">' . form::hidden('im_order', '') . $core->formNonce();
599        echo '<input type="submit" name="updateaction" value="' . __('Update menu') . '" />' . '</p>';
600        echo '<p class="col right">' . '<input id="remove-action" type="submit" class="delete" name="removeaction" ' .
601        'value="' . __('Delete selected menu items') . '" ' .
602        'onclick="return window.confirm(\'' . html::escapeJS(__('Are you sure you want to remove selected menu items?')) . '\');" />' .
603            '</p>';
604        echo '</div>';
605        echo '</form>';
606    }
607} else {
608    echo
609    '<p>' . __('No menu items so far.') . '</p>';
610}
611
612dcPage::helpBlock('simpleMenu');
613?>
614
615</body>
616</html>
Note: See TracBrowser for help on using the repository browser.

Sites map