Dotclear

source: admin/index.php @ 4006:4de7ea99ccac

Revision 4006:4de7ea99ccac, 16.1 KB checked in by franck <carnet.franck.paul@…>, 6 years ago (diff)

If context cannot be conserved when switching blog, test dashboard access permission before killing the session

Line 
1<?php
2/**
3 * @package Dotclear
4 * @subpackage Backend
5 *
6 * @copyright Olivier Meunier & Association Dotclear
7 * @copyright GPL-2.0-only
8 */
9
10if (!empty($_GET['pf'])) {
11    require dirname(__FILE__) . '/../inc/load_plugin_file.php';
12    exit;
13}
14
15if (!empty($_GET['vf'])) {
16    require dirname(__FILE__) . '/../inc/load_var_file.php';
17    exit;
18}
19
20require dirname(__FILE__) . '/../inc/admin/prepend.php';
21
22if (!empty($_GET['default_blog'])) {
23    try {
24        $core->setUserDefaultBlog($core->auth->userID(), $core->blog->id);
25        $core->adminurl->redirect("admin.home");
26    } catch (Exception $e) {
27        $core->error->add($e->getMessage());
28    }
29}
30
31dcPage::check('usage,contentadmin', true);
32
33if ($core->plugins->disableDepModules($core->adminurl->get('admin.home', []))) {
34    exit;
35}
36
37# Logout
38if (!empty($_GET['logout'])) {
39    $core->session->destroy();
40    if (isset($_COOKIE['dc_admin'])) {
41        unset($_COOKIE['dc_admin']);
42        setcookie('dc_admin', false, -600, '', '', DC_ADMIN_SSL);
43    }
44    $core->adminurl->redirect("admin.auth");
45    exit;
46}
47
48# Plugin install
49$plugins_install = $core->plugins->installModules();
50
51# Check dashboard module prefs
52$ws = $core->auth->user_prefs->addWorkspace('dashboard');
53if (!$core->auth->user_prefs->dashboard->prefExists('doclinks')) {
54    if (!$core->auth->user_prefs->dashboard->prefExists('doclinks', true)) {
55        $core->auth->user_prefs->dashboard->put('doclinks', true, 'boolean', '', null, true);
56    }
57    $core->auth->user_prefs->dashboard->put('doclinks', true, 'boolean');
58}
59if (!$core->auth->user_prefs->dashboard->prefExists('dcnews')) {
60    if (!$core->auth->user_prefs->dashboard->prefExists('dcnews', true)) {
61        $core->auth->user_prefs->dashboard->put('dcnews', true, 'boolean', '', null, true);
62    }
63    $core->auth->user_prefs->dashboard->put('dcnews', true, 'boolean');
64}
65if (!$core->auth->user_prefs->dashboard->prefExists('quickentry')) {
66    if (!$core->auth->user_prefs->dashboard->prefExists('quickentry', true)) {
67        $core->auth->user_prefs->dashboard->put('quickentry', false, 'boolean', '', null, true);
68    }
69    $core->auth->user_prefs->dashboard->put('quickentry', false, 'boolean');
70}
71if (!$core->auth->user_prefs->dashboard->prefExists('nodcupdate')) {
72    if (!$core->auth->user_prefs->dashboard->prefExists('nodcupdate', true)) {
73        $core->auth->user_prefs->dashboard->put('nodcupdate', false, 'boolean', '', null, true);
74    }
75    $core->auth->user_prefs->dashboard->put('nodcupdate', false, 'boolean');
76}
77
78// Handle folded/unfolded sections in admin from user preferences
79$ws = $core->auth->user_prefs->addWorkspace('toggles');
80if (!$core->auth->user_prefs->toggles->prefExists('unfolded_sections')) {
81    $core->auth->user_prefs->toggles->put('unfolded_sections', '', 'string', 'Folded sections in admin', null, true);
82}
83
84# Dashboard icons
85$__dashboard_icons = new ArrayObject();
86
87$favs = $core->favs->getUserFavorites();
88$core->favs->appendDashboardIcons($__dashboard_icons);
89
90# Check plugins and themes update from repository
91$checkStoreUpdate = function ($mod, $url, $img, $icon) {
92    $repo = new dcStore($mod, $url);
93    $upd  = $repo->get(true);
94    if (!empty($upd)) {
95        $icon[0] .= '<br />' . sprintf(__('An update is available', '%s updates are available.', count($upd)), count($upd));
96        $icon[1] .= '#update';
97        $icon[2] = 'images/menu/' . $img . '-b-update.png';
98    }
99};
100if (isset($__dashboard_icons['plugins'])) {
101    $checkStoreUpdate($core->plugins, $core->blog->settings->system->store_plugin_url, 'plugins', $__dashboard_icons['plugins']);
102}
103if (isset($__dashboard_icons['blog_theme'])) {
104    $themes = new dcThemes($core);
105    $themes->loadModules($core->blog->themes_path, null);
106    $checkStoreUpdate($themes, $core->blog->settings->system->store_theme_url, 'blog-theme', $__dashboard_icons['blog_theme']);
107}
108
109# Latest news for dashboard
110$__dashboard_items = new ArrayObject([new ArrayObject(), new ArrayObject()]);
111
112$dashboardItem = 0;
113
114# Documentation links
115if ($core->auth->user_prefs->dashboard->doclinks) {
116    if (!empty($__resources['doc'])) {
117        $doc_links = '<div class="box small dc-box" id="doc-and-support"><h3>' . __('Documentation and support') . '</h3><ul>';
118
119        foreach ($__resources['doc'] as $k => $v) {
120            $doc_links .= '<li><a class="outgoing" href="' . $v . '" title="' . $k . '">' . $k .
121                ' <img src="images/outgoing-link.svg" alt="" /></a></li>';
122        }
123
124        $doc_links .= '</ul></div>';
125        $__dashboard_items[$dashboardItem][] = $doc_links;
126        $dashboardItem++;
127    }
128}
129
130$core->callBehavior('adminDashboardItems', $core, $__dashboard_items);
131
132# Dashboard content
133$__dashboard_contents = new ArrayObject([new ArrayObject, new ArrayObject]);
134$core->callBehavior('adminDashboardContents', $core, $__dashboard_contents);
135
136# Editor stuff
137$admin_post_behavior = '';
138if ($core->auth->user_prefs->dashboard->quickentry) {
139    if ($core->auth->check('usage,contentadmin', $core->blog->id)) {
140        $post_format = $core->auth->getOption('post_format');
141        $post_editor = $core->auth->getOption('editor');
142        if ($post_editor && !empty($post_editor[$post_format])) {
143            // context is not post because of tags not available
144            $admin_post_behavior = $core->callBehavior('adminPostEditor', $post_editor[$post_format], 'quickentry', ['#post_content'], $post_format);
145        }
146    }
147}
148
149# Dashboard drag'n'drop switch for its elements
150$core->auth->user_prefs->addWorkspace('accessibility');
151$dragndrop      = '';
152$dragndrop_head = '';
153$dragndrop_msg  = [
154    'dragndrop_off' => __('Dashboard area\'s drag and drop is disabled'),
155    'dragndrop_on'  => __('Dashboard area\'s drag and drop is enabled')
156];
157if (!$core->auth->user_prefs->accessibility->nodragdrop) {
158    $dragndrop_head = dcPage::jsJson('dotclear_dragndrop', $dragndrop_msg);
159    $dragndrop      =
160    '<input type="checkbox" id="dragndrop" class="sr-only" title="' . $dragndrop_msg['dragndrop_off'] . '" />' .
161    '<label for="dragndrop">' .
162    '<svg aria-hidden="true" focusable="false" class="dragndrop-svg">' .
163    '<use xlink:href="images/dragndrop.svg#mask"></use>' .
164    '</svg>' .
165    '<span id="dragndrop-label" class="sr-only">' . $dragndrop_msg['dragndrop_off'] . '</span>' .
166        '</label>';
167}
168
169/* DISPLAY
170-------------------------------------------------------- */
171dcPage::open(__('Dashboard'),
172    dcPage::jsLoad('js/jquery/jquery-ui.custom.js') .
173    dcPage::jsLoad('js/jquery/jquery.ui.touch-punch.js') .
174    dcPage::jsLoad('js/_index.js') .
175    $dragndrop_head .
176    $admin_post_behavior .
177    # --BEHAVIOR-- adminDashboardHeaders
178    $core->callBehavior('adminDashboardHeaders'),
179    dcPage::breadcrumb(
180        [
181            __('Dashboard') . ' : ' . html::escapeHTML($core->blog->name) => ''
182        ],
183        ['home_link' => false]
184    )
185);
186
187if ($core->auth->getInfo('user_default_blog') != $core->blog->id && $core->auth->getBlogCount() > 1) {
188    echo
189    '<p><a href="' . $core->adminurl->get("admin.home", ['default_blog' => 1]) . '" class="button">' . __('Make this blog my default blog') . '</a></p>';
190}
191
192if ($core->blog->status == 0) {
193    echo '<p class="static-msg">' . __('This blog is offline') . '.</p>';
194} elseif ($core->blog->status == -1) {
195    echo '<p class="static-msg">' . __('This blog is removed') . '.</p>';
196}
197
198if (!defined('DC_ADMIN_URL') || !DC_ADMIN_URL) {
199    echo
200    '<p class="static-msg">' .
201    sprintf(__('%s is not defined, you should edit your configuration file.'), 'DC_ADMIN_URL') .
202    ' ' . __('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.') .
203        '</p>';
204}
205
206if (!defined('DC_ADMIN_MAILFROM') || !DC_ADMIN_MAILFROM) {
207    echo
208    '<p class="static-msg">' .
209    sprintf(__('%s is not defined, you should edit your configuration file.'), 'DC_ADMIN_MAILFROM') .
210    ' ' . __('See <a href="http://dotclear.org/documentation/2.0/admin/config">documentation</a> for more information.') .
211        '</p>';
212}
213
214$err = [];
215
216# Check cache directory
217if ($core->auth->isSuperAdmin()) {
218    if (!is_dir(DC_TPL_CACHE) || !is_writable(DC_TPL_CACHE)) {
219        $err[] = '<p>' . __("The cache directory does not exist or is not writable. You must create this directory with sufficient rights and affect this location to \"DC_TPL_CACHE\" in inc/config.php file.") . '</p>';
220    }
221} else {
222    if (!is_dir(DC_TPL_CACHE) || !is_writable(DC_TPL_CACHE)) {
223        $err[] = '<p>' . __("The cache directory does not exist or is not writable. You should contact your administrator.") . '</p>';
224    }
225}
226
227# Check public directory
228if ($core->auth->isSuperAdmin()) {
229    if (!is_dir($core->blog->public_path) || !is_writable($core->blog->public_path)) {
230        $err[] = '<p>' . __("There is no writable directory /public/ at the location set in about:config \"public_path\". You must create this directory with sufficient rights (or change this setting).") . '</p>';
231    }
232} else {
233    if (!is_dir($core->blog->public_path) || !is_writable($core->blog->public_path)) {
234        $err[] = '<p>' . __("There is no writable root directory for the media manager. You should contact your administrator.") . '</p>';
235    }
236}
237
238# Error list
239if (count($err) > 0) {
240    echo '<div class="error"><p><strong>' . __('Error:') . '</strong></p>' .
241    '<ul><li>' . implode("</li><li>", $err) . '</li></ul></div>';
242}
243
244# Plugins install messages
245if (!empty($plugins_install['success'])) {
246    echo '<div class="success">' . __('Following plugins have been installed:') . '<ul>';
247    foreach ($plugins_install['success'] as $k => $v) {
248        echo '<li>' . $k . '</li>';
249    }
250    echo '</ul></div>';
251}
252if (!empty($plugins_install['failure'])) {
253    echo '<div class="error">' . __('Following plugins have not been installed:') . '<ul>';
254    foreach ($plugins_install['failure'] as $k => $v) {
255        echo '<li>' . $k . ' (' . $v . ')</li>';
256    }
257    echo '</ul></div>';
258}
259# Errors modules notifications
260if ($core->auth->isSuperAdmin()) {
261    $list = $core->plugins->getErrors();
262    if (!empty($list)) {
263        echo
264        '<div class="error" id="module-errors" class="error"><p>' . __('Errors have occured with following plugins:') . '</p> ' .
265        '<ul><li>' . implode("</li>\n<li>", $list) . '</li></ul></div>';
266    }
267}
268
269# Get current main orders
270$main_order = $core->auth->user_prefs->dashboard->main_order;
271$main_order = ($main_order != '' ? explode(',', $main_order) : []);
272
273# Get current boxes orders
274$boxes_order = $core->auth->user_prefs->dashboard->boxes_order;
275$boxes_order = ($boxes_order != '' ? explode(',', $boxes_order) : []);
276
277# Get current boxes items orders
278$boxes_items_order = $core->auth->user_prefs->dashboard->boxes_items_order;
279$boxes_items_order = ($boxes_items_order != '' ? explode(',', $boxes_items_order) : []);
280
281# Get current boxes contents orders
282$boxes_contents_order = $core->auth->user_prefs->dashboard->boxes_contents_order;
283$boxes_contents_order = ($boxes_contents_order != '' ? explode(',', $boxes_contents_order) : []);
284
285$composeItems = function ($list, $blocks, $flat = false) {
286
287    $ret   = [];
288    $items = [];
289
290    if ($flat) {
291        $items = $blocks;
292    } else {
293        foreach ($blocks as $i) {
294            foreach ($i as $v) {
295                $items[] = $v;
296            }
297        }
298    }
299
300    # First loop to find ordered indexes
301    $order = [];
302    $index = 0;
303    foreach ($items as $v) {
304        if (preg_match('/<div.*?id="([^"].*?)".*?>/ms', $v, $match)) {
305            $id       = $match[1];
306            $position = array_search($id, $list, true);
307            if ($position !== false) {
308                $order[$position] = $index;
309            }
310        }
311        $index++;
312    }
313
314    # Second loop to combine ordered items
315    $index = 0;
316    foreach ($items as $v) {
317        $position = array_search($index, $order, true);
318        if ($position !== false) {
319            $ret[$position] = $v;
320        }
321        $index++;
322    }
323    # Reorder items on their position (key)
324    ksort($ret);
325
326    # Third loop to combine unordered items
327    $index = 0;
328    foreach ($items as $v) {
329        $position = array_search($index, $order, true);
330        if ($position === false) {
331            $ret[count($ret)] = $v;
332        }
333        $index++;
334    }
335
336    return join('', $ret);
337};
338
339# Compose dashboard items (doc, …)
340$dashboardItems = $composeItems($boxes_items_order, $__dashboard_items);
341# Compose dashboard contents (plugin's modules)
342$dashboardContents = $composeItems($boxes_contents_order, $__dashboard_contents);
343
344$__dashboard_boxes = [];
345if ($dashboardItems != '') {
346    $__dashboard_boxes[] = '<div class="db-items" id="db-items">' . $dashboardItems . '</div>';
347}
348if ($dashboardContents != '') {
349    $__dashboard_boxes[] = '<div class="db-contents" id="db-contents">' . $dashboardContents . '</div>';
350}
351$dashboardBoxes = $composeItems($boxes_order, $__dashboard_boxes, true);
352
353# Compose main area
354$__dashboard_main = [];
355if (!$core->auth->user_prefs->dashboard->nofavicons) {
356    # Dashboard icons
357    $dashboardIcons = '<div id="icons">';
358    foreach ($__dashboard_icons as $i) {
359        $dashboardIcons .= '<p><a href="' . $i[1] . '"><img src="' . dc_admin_icon_url($i[2]) . '" alt="" />' .
360            '<br /><span class="db-icon-title">' . $i[0] . '</span></a></p>';
361    }
362    $dashboardIcons .= '</div>';
363    $__dashboard_main[] = $dashboardIcons;
364}
365if ($core->auth->user_prefs->dashboard->quickentry) {
366    if ($core->auth->check('usage,contentadmin', $core->blog->id)) {
367        # Getting categories
368        $categories_combo = dcAdminCombos::getCategoriesCombo(
369            $core->blog->getCategories([])
370        );
371
372        $dashboardQuickEntry =
373        '<div id="quick">' .
374        '<h3>' . __('Quick entry') . sprintf(' &rsaquo; %s', $core->auth->getOption('post_format')) . '</h3>' .
375        '<form id="quick-entry" action="' . $core->adminurl->get('admin.post') . '" method="post" class="fieldset">' .
376        '<h4>' . __('New entry') . '</h4>' .
377        '<p class="col"><label for="post_title" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label>' .
378        form::field('post_title', 20, 255, [
379            'class'      => 'maximal',
380            'extra_html' => 'required placeholder="' . __('Title') . '"'
381        ]) .
382        '</p>' .
383        '<div class="area"><label class="required" ' .
384        'for="post_content"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Content:') . '</label> ' .
385        form::textarea('post_content', 50, 10, ['extra_html' => 'required placeholder="' . __('Content') . '"']) .
386        '</div>' .
387        '<p><label for="cat_id" class="classic">' . __('Category:') . '</label> ' .
388        form::combo('cat_id', $categories_combo) . '</p>' .
389        ($core->auth->check('categories', $core->blog->id)
390            ? '<div>' .
391            '<p id="new_cat" class="q-cat">' . __('Add a new category') . '</p>' .
392            '<p class="q-cat"><label for="new_cat_title">' . __('Title:') . '</label> ' .
393            form::field('new_cat_title', 30, 255) . '</p>' .
394            '<p class="q-cat"><label for="new_cat_parent">' . __('Parent:') . '</label> ' .
395            form::combo('new_cat_parent', $categories_combo) .
396            '</p>' .
397            '<p class="form-note info clear">' . __('This category will be created when you will save your post.') . '</p>' .
398            '</div>'
399            : '') .
400        '<p><input type="submit" value="' . __('Save') . '" name="save" /> ' .
401        ($core->auth->check('publish', $core->blog->id)
402            ? '<input type="hidden" value="' . __('Save and publish') . '" name="save-publish" />'
403            : '') .
404        $core->formNonce() .
405        form::hidden('post_status', -2) .
406        form::hidden('post_format', $core->auth->getOption('post_format')) .
407        form::hidden('post_excerpt', '') .
408        form::hidden('post_lang', $core->auth->getInfo('user_lang')) .
409        form::hidden('post_notes', '') .
410            '</p>' .
411            '</form>' .
412            '</div>';
413        $__dashboard_main[] = $dashboardQuickEntry;
414    }
415}
416if ($dashboardBoxes != '') {
417    $__dashboard_main[] = '<div id="dashboard-boxes">' . $dashboardBoxes . '</div>';
418}
419$dashboardMain = $composeItems($main_order, $__dashboard_main, true);
420
421echo $dragndrop . '<div id="dashboard-main">' . $dashboardMain . '</div>';
422
423dcPage::helpBlock('core_dashboard');
424dcPage::close();
Note: See TracBrowser for help on using the repository browser.

Sites map