Dotclear

source: admin/services.php @ 3781:a86e029cb95d

Revision 3781:a86e029cb95d, 21.4 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

Animate some counters on dashboard icons (nb of comments, spam comments and posts), just for fun

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
10require dirname(__FILE__) . '/../inc/admin/prepend.php';
11
12$core->rest->addFunction('getPostsCount', array('dcRestMethods', 'getPostsCount'));
13$core->rest->addFunction('getCommentsCount', array('dcRestMethods', 'getCommentsCount'));
14$core->rest->addFunction('checkNewsUpdate', array('dcRestMethods', 'checkNewsUpdate'));
15$core->rest->addFunction('checkCoreUpdate', array('dcRestMethods', 'checkCoreUpdate'));
16$core->rest->addFunction('getPostById', array('dcRestMethods', 'getPostById'));
17$core->rest->addFunction('getCommentById', array('dcRestMethods', 'getCommentById'));
18$core->rest->addFunction('quickPost', array('dcRestMethods', 'quickPost'));
19$core->rest->addFunction('validatePostMarkup', array('dcRestMethods', 'validatePostMarkup'));
20$core->rest->addFunction('getZipMediaContent', array('dcRestMethods', 'getZipMediaContent'));
21$core->rest->addFunction('getMeta', array('dcRestMethods', 'getMeta'));
22$core->rest->addFunction('delMeta', array('dcRestMethods', 'delMeta'));
23$core->rest->addFunction('setPostMeta', array('dcRestMethods', 'setPostMeta'));
24$core->rest->addFunction('searchMeta', array('dcRestMethods', 'searchMeta'));
25$core->rest->addFunction('setSectionFold', array('dcRestMethods', 'setSectionFold'));
26$core->rest->addFunction('getModuleById', array('dcRestMethods', 'getModuleById'));
27
28$core->rest->serve();
29
30/* Common REST methods */
31class dcRestMethods
32{
33    /**
34     * Serve method to get number of posts (whatever are their status) for current blog.
35     *
36     * @param     core     <b>dcCore</b>     dcCore instance
37     * @param     get     <b>array</b>     cleaned $_GET
38     */
39    public static function getPostsCount($core, $get)
40    {
41        $count = $core->blog->getPosts(array(), true)->f(0);
42        $str   = sprintf(__('%d post', '%d posts', $count), $count);
43
44        $rsp      = new xmlTag('count');
45        $rsp->ret = $str;
46
47        return $rsp;
48    }
49
50    /**
51     * Serve method to get number of comments (whatever are their status) for current blog.
52     *
53     * @param     core     <b>dcCore</b>     dcCore instance
54     * @param     get     <b>array</b>     cleaned $_GET
55     */
56    public static function getCommentsCount($core, $get)
57    {
58        $count = $core->blog->getComments(array(), true)->f(0);
59        $str   = sprintf(__('%d comment', '%d comments', $count), $count);
60
61        $rsp      = new xmlTag('count');
62        $rsp->ret = $str;
63
64        return $rsp;
65    }
66
67    public static function checkNewsUpdate($core, $get)
68    {
69        # Dotclear news
70
71        $rsp        = new xmlTag('news');
72        $rsp->check = false;
73        $ret        = __('Dotclear news not available');
74
75        if ($core->auth->user_prefs->dashboard->dcnews) {
76            try
77            {
78
79                if (empty($GLOBALS['__resources']['rss_news'])) {
80                    throw new Exception();
81                }
82                $feed_reader = new feedReader;
83                $feed_reader->setCacheDir(DC_TPL_CACHE);
84                $feed_reader->setTimeout(2);
85                $feed_reader->setUserAgent('Dotclear - http://www.dotclear.org/');
86                $feed = $feed_reader->parse($GLOBALS['__resources']['rss_news']);
87                if ($feed) {
88                    $ret = '<div class="box medium dc-box"><h3>' . __('Dotclear news') . '</h3><dl id="news">';
89                    $i   = 1;
90                    foreach ($feed->items as $item) {
91                        $dt = isset($item->link) ? '<a href="' . $item->link . '" class="outgoing" title="' . $item->title . '">' .
92                        $item->title . ' <img src="images/outgoing-link.svg" alt="" /></a>' : $item->title;
93
94                        if ($i < 3) {
95                            $ret .=
96                            '<dt>' . $dt . '</dt>' .
97                            '<dd><p><strong>' . dt::dt2str(__('%d %B %Y:'), $item->pubdate, 'Europe/Paris') . '</strong> ' .
98                            '<em>' . text::cutString(html::clean($item->content), 120) . '...</em></p></dd>';
99                        } else {
100                            $ret .=
101                            '<dt>' . $dt . '</dt>' .
102                            '<dd>' . dt::dt2str(__('%d %B %Y:'), $item->pubdate, 'Europe/Paris') . '</dd>';
103                        }
104                        $i++;
105                        if ($i > 2) {break;}
106                    }
107                    $ret .= '</dl></div>';
108                    $rsp->check = true;
109                }
110            } catch (Exception $e) {}
111        }
112        $rsp->ret = $ret;
113        return $rsp;
114    }
115
116    public static function checkCoreUpdate($core, $get)
117    {
118        # Dotclear updates notifications
119
120        $rsp        = new xmlTag('update');
121        $rsp->check = false;
122        $ret        = __('Dotclear update not available');
123
124        if ($core->auth->isSuperAdmin() && !DC_NOT_UPDATE && is_readable(DC_DIGESTS) &&
125            !$core->auth->user_prefs->dashboard->nodcupdate) {
126            $updater      = new dcUpdate(DC_UPDATE_URL, 'dotclear', DC_UPDATE_VERSION, DC_TPL_CACHE . '/versions');
127            $new_v        = $updater->check(DC_VERSION);
128            $version_info = $new_v ? $updater->getInfoURL() : '';
129
130            if ($updater->getNotify() && $new_v) {
131                // Check PHP version required
132                if (version_compare(phpversion(), $updater->getPHPVersion()) >= 0) {
133                    $ret =
134                    '<div class="dc-update"><h3>' . sprintf(__('Dotclear %s is available!'), $new_v) . '</h3> ' .
135                    '<p><a class="button submit" href="' . $core->adminurl->get("admin.update") . '">' . sprintf(__('Upgrade now'), $new_v) . '</a> ' .
136                    '<a class="button" href="' . $core->adminurl->get("admin.update", array('hide_msg' => 1)) . '">' . __('Remind me later') . '</a>' .
137                        ($version_info ? ' </p>' .
138                        '<p class="updt-info"><a href="' . $version_info . '">' . __('Information about this version') . '</a>' : '') . '</p>' .
139                        '</div>';
140                } else {
141                    $ret = '<p class="info">' .
142                    sprintf(__('A new version of Dotclear is available but needs PHP version ≥ %s, your\'s is currently %s'),
143                        $updater->getPHPVersion(), phpversion()) .
144                        '</p>';
145                }
146                $rsp->check = true;
147            } else {
148                if (version_compare(phpversion(), DC_NEXT_REQUIRED_PHP, '<')) {
149                    $ret = '<p class="info">' .
150                    sprintf(__('The next versions of Dotclear will not support PHP version < %s, your\'s is currently %s'),
151                        DC_NEXT_REQUIRED_PHP, phpversion()) .
152                        '</p>';
153                    $rsp->check = true;
154                }
155            }
156        }
157        $rsp->ret = $ret;
158        return $rsp;
159    }
160
161    public static function getPostById($core, $get)
162    {
163        if (empty($get['id'])) {
164            throw new Exception('No post ID');
165        }
166
167        $params = array('post_id' => (integer) $get['id']);
168
169        if (isset($get['post_type'])) {
170            $params['post_type'] = $get['post_type'];
171        }
172
173        $rs = $core->blog->getPosts($params);
174
175        if ($rs->isEmpty()) {
176            throw new Exception('No post for this ID');
177        }
178
179        $rsp     = new xmlTag('post');
180        $rsp->id = $rs->post_id;
181
182        $rsp->blog_id($rs->blog_id);
183        $rsp->user_id($rs->user_id);
184        $rsp->cat_id($rs->cat_id);
185        $rsp->post_dt($rs->post_dt);
186        $rsp->post_creadt($rs->post_creadt);
187        $rsp->post_upddt($rs->post_upddt);
188        $rsp->post_format($rs->post_format);
189        $rsp->post_url($rs->post_url);
190        $rsp->post_lang($rs->post_lang);
191        $rsp->post_title($rs->post_title);
192        $rsp->post_excerpt($rs->post_excerpt);
193        $rsp->post_excerpt_xhtml($rs->post_excerpt_xhtml);
194        $rsp->post_content($rs->post_content);
195        $rsp->post_content_xhtml($rs->post_content_xhtml);
196        $rsp->post_notes($rs->post_notes);
197        $rsp->post_status($rs->post_status);
198        $rsp->post_selected($rs->post_selected);
199        $rsp->post_open_comment($rs->post_open_comment);
200        $rsp->post_open_tb($rs->post_open_tb);
201        $rsp->nb_comment($rs->nb_comment);
202        $rsp->nb_trackback($rs->nb_trackback);
203        $rsp->user_name($rs->user_name);
204        $rsp->user_firstname($rs->user_firstname);
205        $rsp->user_displayname($rs->user_displayname);
206        $rsp->user_email($rs->user_email);
207        $rsp->user_url($rs->user_url);
208        $rsp->cat_title($rs->cat_title);
209        $rsp->cat_url($rs->cat_url);
210
211        $rsp->post_display_content($rs->getContent(true));
212        $rsp->post_display_excerpt($rs->getExcerpt(true));
213
214        $metaTag = new xmlTag('meta');
215        if (($meta = @unserialize($rs->post_meta)) !== false) {
216            foreach ($meta as $K => $V) {
217                foreach ($V as $v) {
218                    $metaTag->$K($v);
219                }
220            }
221        }
222        $rsp->post_meta($metaTag);
223
224        return $rsp;
225    }
226
227    public static function getCommentById($core, $get)
228    {
229        if (empty($get['id'])) {
230            throw new Exception('No comment ID');
231        }
232
233        $rs = $core->blog->getComments(array('comment_id' => (integer) $get['id']));
234
235        if ($rs->isEmpty()) {
236            throw new Exception('No comment for this ID');
237        }
238
239        $rsp     = new xmlTag('post');
240        $rsp->id = $rs->comment_id;
241
242        $rsp->comment_dt($rs->comment_dt);
243        $rsp->comment_upddt($rs->comment_upddt);
244        $rsp->comment_author($rs->comment_author);
245        $rsp->comment_site($rs->comment_site);
246        $rsp->comment_content($rs->comment_content);
247        $rsp->comment_trackback($rs->comment_trackback);
248        $rsp->comment_status($rs->comment_status);
249        $rsp->post_title($rs->post_title);
250        $rsp->post_url($rs->post_url);
251        $rsp->post_id($rs->post_id);
252        $rsp->post_dt($rs->post_dt);
253        $rsp->user_id($rs->user_id);
254
255        $rsp->comment_display_content($rs->getContent(true));
256
257        if ($core->auth->userID()) {
258            $rsp->comment_ip($rs->comment_ip);
259            $rsp->comment_email($rs->comment_email);
260            $rsp->comment_spam_disp(dcAntispam::statusMessage($rs));
261        }
262
263        return $rsp;
264    }
265
266    public static function quickPost($core, $get, $post)
267    {
268        # Create category
269        if (!empty($post['new_cat_title']) && $core->auth->check('categories', $core->blog->id)) {
270
271            $cur_cat            = $core->con->openCursor($core->prefix . 'category');
272            $cur_cat->cat_title = $post['new_cat_title'];
273            $cur_cat->cat_url   = '';
274
275            $parent_cat = !empty($post['new_cat_parent']) ? $post['new_cat_parent'] : '';
276
277            # --BEHAVIOR-- adminBeforeCategoryCreate
278            $core->callBehavior('adminBeforeCategoryCreate', $cur_cat);
279
280            $post['cat_id'] = $core->blog->addCategory($cur_cat, (integer) $parent_cat);
281
282            # --BEHAVIOR-- adminAfterCategoryCreate
283            $core->callBehavior('adminAfterCategoryCreate', $cur_cat, $post['cat_id']);
284        }
285
286        $cur = $core->con->openCursor($core->prefix . 'post');
287
288        $cur->post_title        = !empty($post['post_title']) ? $post['post_title'] : '';
289        $cur->user_id           = $core->auth->userID();
290        $cur->post_content      = !empty($post['post_content']) ? $post['post_content'] : '';
291        $cur->cat_id            = !empty($post['cat_id']) ? (integer) $post['cat_id'] : null;
292        $cur->post_format       = !empty($post['post_format']) ? $post['post_format'] : 'xhtml';
293        $cur->post_lang         = !empty($post['post_lang']) ? $post['post_lang'] : '';
294        $cur->post_status       = !empty($post['post_status']) ? (integer) $post['post_status'] : 0;
295        $cur->post_open_comment = (integer) $core->blog->settings->system->allow_comments;
296        $cur->post_open_tb      = (integer) $core->blog->settings->system->allow_trackbacks;
297
298        # --BEHAVIOR-- adminBeforePostCreate
299        $core->callBehavior('adminBeforePostCreate', $cur);
300
301        $return_id = $core->blog->addPost($cur);
302
303        # --BEHAVIOR-- adminAfterPostCreate
304        $core->callBehavior('adminAfterPostCreate', $cur, $return_id);
305
306        $rsp     = new xmlTag('post');
307        $rsp->id = $return_id;
308
309        $post = $core->blog->getPosts(array('post_id' => $return_id));
310
311        $rsp->post_status = $post->post_status;
312        $rsp->post_url    = $post->getURL();
313        return $rsp;
314    }
315
316    public static function validatePostMarkup($core, $get, $post)
317    {
318        if (!isset($post['excerpt'])) {
319            throw new Exception('No entry excerpt');
320        }
321
322        if (!isset($post['content'])) {
323            throw new Exception('No entry content');
324        }
325
326        if (empty($post['format'])) {
327            throw new Exception('No entry format');
328        }
329
330        if (!isset($post['lang'])) {
331            throw new Exception('No entry lang');
332        }
333
334        $excerpt       = $post['excerpt'];
335        $excerpt_xhtml = '';
336        $content       = $post['content'];
337        $content_xhtml = '';
338        $format        = $post['format'];
339        $lang          = $post['lang'];
340
341        $core->blog->setPostContent(0, $format, $lang, $excerpt, $excerpt_xhtml, $content, $content_xhtml);
342
343        $rsp = new xmlTag('result');
344
345        $v = htmlValidator::validate($excerpt_xhtml . $content_xhtml);
346
347        $rsp->valid($v['valid']);
348        $rsp->errors($v['errors']);
349
350        return $rsp;
351    }
352
353    public static function getZipMediaContent($core, $get, $post)
354    {
355        if (empty($get['id'])) {
356            throw new Exception('No media ID');
357        }
358
359        $id = (integer) $get['id'];
360
361        if (!$core->auth->check('media,media_admin', $core->blog)) {
362            throw new Exception('Permission denied');
363        }
364
365        try {
366            $core->media = new dcMedia($core);
367            $file        = $core->media->getFile($id);
368        } catch (Exception $e) {}
369
370        if ($file === null || $file->type != 'application/zip' || !$file->editable) {
371            throw new Exception('Not a valid file');
372        }
373
374        $rsp     = new xmlTag('result');
375        $content = $core->media->getZipContent($file);
376
377        foreach ($content as $k => $v) {
378            $rsp->file($k);
379        }
380
381        return $rsp;
382    }
383
384    public static function getMeta($core, $get)
385    {
386        $postid   = !empty($get['postId']) ? $get['postId'] : null;
387        $limit    = !empty($get['limit']) ? $get['limit'] : null;
388        $metaId   = !empty($get['metaId']) ? $get['metaId'] : null;
389        $metaType = !empty($get['metaType']) ? $get['metaType'] : null;
390
391        $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc';
392
393        $rs = $core->meta->getMetadata(array(
394            'meta_type' => $metaType,
395            'limit'     => $limit,
396            'meta_id'   => $metaId,
397            'post_id'   => $postid));
398        $rs = $core->meta->computeMetaStats($rs);
399
400        $sortby = explode(',', $sortby);
401        $sort   = $sortby[0];
402        $order  = isset($sortby[1]) ? $sortby[1] : 'asc';
403
404        switch ($sort) {
405            case 'metaId':
406                $sort = 'meta_id_lower';
407                break;
408            case 'count':
409                $sort = 'count';
410                break;
411            case 'metaType':
412                $sort = 'meta_type';
413                break;
414            default:
415                $sort = 'meta_type';
416        }
417
418        $rs->sort($sort, $order);
419
420        $rsp = new xmlTag();
421
422        while ($rs->fetch()) {
423            $metaTag               = new xmlTag('meta');
424            $metaTag->type         = $rs->meta_type;
425            $metaTag->uri          = rawurlencode($rs->meta_id);
426            $metaTag->count        = $rs->count;
427            $metaTag->percent      = $rs->percent;
428            $metaTag->roundpercent = $rs->roundpercent;
429            $metaTag->CDATA($rs->meta_id);
430
431            $rsp->insertNode($metaTag);
432        }
433
434        return $rsp;
435    }
436
437    public static function setPostMeta($core, $get, $post)
438    {
439        if (empty($post['postId'])) {
440            throw new Exception('No post ID');
441        }
442
443        if (empty($post['meta']) && $post['meta'] != '0') {
444            throw new Exception('No meta');
445        }
446
447        if (empty($post['metaType'])) {
448            throw new Exception('No meta type');
449        }
450
451        # Get previous meta for post
452        $post_meta = $core->meta->getMetadata(array(
453            'meta_type' => $post['metaType'],
454            'post_id'   => $post['postId']));
455        $pm = array();
456        while ($post_meta->fetch()) {
457            $pm[] = $post_meta->meta_id;
458        }
459
460        foreach ($core->meta->splitMetaValues($post['meta']) as $m) {
461            if (!in_array($m, $pm)) {
462                $core->meta->setPostMeta($post['postId'], $post['metaType'], $m);
463            }
464        }
465
466        return true;
467    }
468
469    public static function delMeta($core, $get, $post)
470    {
471        if (empty($post['postId'])) {
472            throw new Exception('No post ID');
473        }
474
475        if (empty($post['metaId']) && $post['metaId'] != '0') {
476            throw new Exception('No meta ID');
477        }
478
479        if (empty($post['metaType'])) {
480            throw new Exception('No meta type');
481        }
482
483        $core->meta->delPostMeta($post['postId'], $post['metaType'], $post['metaId']);
484
485        return true;
486    }
487
488    public static function searchMeta($core, $get)
489    {
490        $q        = !empty($get['q']) ? $get['q'] : null;
491        $metaType = !empty($get['metaType']) ? $get['metaType'] : null;
492
493        $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc';
494
495        $rs = $core->meta->getMetadata(array('meta_type' => $metaType));
496        $rs = $core->meta->computeMetaStats($rs);
497
498        $sortby = explode(',', $sortby);
499        $sort   = $sortby[0];
500        $order  = isset($sortby[1]) ? $sortby[1] : 'asc';
501
502        switch ($sort) {
503            case 'metaId':
504                $sort = 'meta_id_lower';
505                break;
506            case 'count':
507                $sort = 'count';
508                break;
509            case 'metaType':
510                $sort = 'meta_type';
511                break;
512            default:
513                $sort = 'meta_type';
514        }
515
516        $rs->sort($sort, $order);
517
518        $rsp = new xmlTag();
519
520        while ($rs->fetch()) {
521            if (stripos($rs->meta_id, $q) === 0) {
522                $metaTag               = new xmlTag('meta');
523                $metaTag->type         = $rs->meta_type;
524                $metaTag->uri          = rawurlencode($rs->meta_id);
525                $metaTag->count        = $rs->count;
526                $metaTag->percent      = $rs->percent;
527                $metaTag->roundpercent = $rs->roundpercent;
528                $metaTag->CDATA($rs->meta_id);
529
530                $rsp->insertNode($metaTag);
531            }
532        }
533
534        return $rsp;
535    }
536
537    public static function setSectionFold($core, $get, $post)
538    {
539        if (empty($post['section'])) {
540            throw new Exception('No section name');
541        }
542        if ($core->auth->user_prefs->toggles === null) {
543            $core->auth->user_prefs->addWorkspace('toggles');
544        }
545        $section = $post['section'];
546        $status  = isset($post['value']) && ($post['value'] != 0);
547        if ($core->auth->user_prefs->toggles->prefExists('unfolded_sections')) {
548            $toggles = explode(',', trim($core->auth->user_prefs->toggles->unfolded_sections));
549        } else {
550            $toggles = array();
551        }
552        $k = array_search($section, $toggles);
553        if ($status) {
554            // true == Fold section ==> remove it from unfolded list
555            if ($k !== false) {
556                unset($toggles[$k]);
557            }
558        } else {
559            // false == unfold section ==> add it to unfolded list
560            if ($k === false) {
561                $toggles[] = $section;
562            };
563        }
564        $core->auth->user_prefs->toggles->put('unfolded_sections', join(',', $toggles));
565        return true;
566    }
567
568    public static function getModuleById($core, $get, $post)
569    {
570        if (empty($get['id'])) {
571            throw new Exception('No module ID');
572        }
573        if (empty($get['list'])) {
574            throw new Exception('No list ID');
575        }
576
577        $id     = $get['id'];
578        $list   = $get['list'];
579        $module = array();
580
581        if ($list == 'plugin-activate') {
582            $modules = $core->plugins->getModules();
583            if (empty($modules) || !isset($modules[$id])) {
584                throw new Exception('Unknow module ID');
585            }
586            $module = $modules[$id];
587        } elseif ($list == 'plugin-new') {
588            $store = new dcStore(
589                $core->plugins,
590                $core->blog->settings->system->store_plugin_url
591            );
592            $store->check();
593
594            $modules = $store->get();
595            if (empty($modules) || !isset($modules[$id])) {
596                throw new Exception('Unknow module ID');
597            }
598            $module = $modules[$id];
599        } else {
600            // behavior not implemented yet
601        }
602
603        if (empty($module)) {
604            throw new Exception('Unknow module ID');
605        }
606
607        $module = adminModulesList::sanitizeModule($id, $module);
608
609        $rsp     = new xmlTag('module');
610        $rsp->id = $id;
611
612        foreach ($module as $k => $v) {
613            $rsp->{$k}((string) $v);
614        }
615
616        return $rsp;
617    }
618}
Note: See TracBrowser for help on using the repository browser.

Sites map