Dotclear

source: inc/core/class.dc.xmlrpc.php @ 3874:ab8368569446

Revision 3874:ab8368569446, 53.7 KB checked in by franck <carnet.franck.paul@…>, 7 years ago (diff)

short notation for array (array() → [])

RevLine 
[0]1<?php
[3731]2/**
3 * @package Dotclear
4 * @subpackage Core
5 *
6 * @copyright Olivier Meunier & Association Dotclear
7 * @copyright GPL-2.0-only
8 */
9
[3730]10if (!defined('DC_RC_PATH')) {return;}
[0]11
12class dcXmlRpc extends xmlrpcIntrospectionServer
13{
[3730]14    public $core;
15    private $blog_id;
16    private $blog_loaded    = false;
17    private $debug          = false;
18    private $debug_file     = '/tmp/dotclear-xmlrpc.log';
19    private $trace_args     = true;
20    private $trace_response = true;
[2566]21
[3730]22    public function __construct($core, $blog_id)
23    {
24        parent::__construct();
[2566]25
[3730]26        $this->core    = &$core;
27        $this->blog_id = $blog_id;
[2566]28
[3730]29        # Blogger methods
[3874]30        $this->addCallback('blogger.newPost', [$this, 'blogger_newPost'],
31            ['string', 'string', 'string', 'string', 'string', 'string', 'integer'],
[3730]32            'New post');
[2566]33
[3874]34        $this->addCallback('blogger.editPost', [$this, 'blogger_editPost'],
35            ['boolean', 'string', 'string', 'string', 'string', 'string', 'integer'],
[3730]36            'Edit a post');
[2566]37
[3874]38        $this->addCallback('blogger.getPost', [$this, 'blogger_getPost'],
39            ['struct', 'string', 'integer', 'string', 'string'],
[3730]40            'Return a posts by ID');
[2566]41
[3874]42        $this->addCallback('blogger.deletePost', [$this, 'blogger_deletePost'],
43            ['string', 'string', 'string', 'string', 'string', 'integer'],
[3730]44            'Delete a post');
[2566]45
[3874]46        $this->addCallback('blogger.getRecentPosts', [$this, 'blogger_getRecentPosts'],
47            ['array', 'string', 'string', 'string', 'string', 'integer'],
[3730]48            'Return a list of recent posts');
[2566]49
[3874]50        $this->addCallback('blogger.getUsersBlogs', [$this, 'blogger_getUserBlogs'],
51            ['struct', 'string', 'string', 'string'],
[3730]52            "Return user's blog");
[2566]53
[3874]54        $this->addCallback('blogger.getUserInfo', [$this, 'blogger_getUserInfo'],
55            ['struct', 'string', 'string', 'string'],
[3730]56            'Return User Info');
[2566]57
[3730]58        # Metaweblog methods
[3874]59        $this->addCallback('metaWeblog.newPost', [$this, 'mw_newPost'],
60            ['string', 'string', 'string', 'string', 'struct', 'boolean'],
[3730]61            'Creates a new post, and optionnaly publishes it.');
[2566]62
[3874]63        $this->addCallback('metaWeblog.editPost', [$this, 'mw_editPost'],
64            ['boolean', 'string', 'string', 'string', 'struct', 'boolean'],
[3730]65            'Updates information about an existing entry');
[2566]66
[3874]67        $this->addCallback('metaWeblog.getPost', [$this, 'mw_getPost'],
68            ['struct', 'string', 'string', 'string'],
[3730]69            'Returns information about a specific post');
[2566]70
[3874]71        $this->addCallback('metaWeblog.getRecentPosts', [$this, 'mw_getRecentPosts'],
72            ['array', 'string', 'string', 'string', 'integer'],
[3730]73            'List of most recent posts in the system');
[2566]74
[3874]75        $this->addCallback('metaWeblog.getCategories', [$this, 'mw_getCategories'],
76            ['array', 'string', 'string', 'string'],
[3730]77            'List of all categories defined in the weblog');
[2566]78
[3874]79        $this->addCallback('metaWeblog.newMediaObject', [$this, 'mw_newMediaObject'],
80            ['struct', 'string', 'string', 'string', 'struct'],
[3730]81            'Upload a file on the web server');
[2566]82
[3730]83        # MovableType methods
[3874]84        $this->addCallback('mt.getRecentPostTitles', [$this, 'mt_getRecentPostTitles'],
85            ['array', 'string', 'string', 'string', 'integer'],
[3730]86            'List of most recent posts in the system');
[2566]87
[3874]88        $this->addCallback('mt.getCategoryList', [$this, 'mt_getCategoryList'],
89            ['array', 'string', 'string', 'string'],
[3730]90            'List of all categories defined in the weblog');
[2566]91
[3874]92        $this->addCallback('mt.getPostCategories', [$this, 'mt_getPostCategories'],
93            ['array', 'string', 'string', 'string'],
[3730]94            'List of all categories to which the post is assigned');
[2566]95
[3874]96        $this->addCallback('mt.setPostCategories', [$this, 'mt_setPostCategories'],
97            ['boolean', 'string', 'string', 'string', 'array'],
[3730]98            'Sets the categories for a post');
[2566]99
[3874]100        $this->addCallback('mt.publishPost', [$this, 'mt_publishPost'],
101            ['boolean', 'string', 'string', 'string'],
[3730]102            'Retrieve pings list for a post');
[2566]103
[3874]104        $this->addCallback('mt.supportedMethods', [$this, 'listMethods'],
105            [], 'Retrieve information about the XML-RPC methods supported by the server.');
[2566]106
[3874]107        $this->addCallback('mt.supportedTextFilters', [$this, 'mt_supportedTextFilters'],
108            [], 'Retrieve information about supported text filters.');
[2566]109
[3730]110        # WordPress methods
[3874]111        $this->addCallback('wp.getUsersBlogs', [$this, 'wp_getUsersBlogs'],
112            ['array', 'string', 'string'],
[3730]113            'Retrieve the blogs of the user.');
[2566]114
[3874]115        $this->addCallback('wp.getPage', [$this, 'wp_getPage'],
116            ['struct', 'integer', 'integer', 'string', 'string'],
[3730]117            'Get the page identified by the page ID.');
[2566]118
[3874]119        $this->addCallback('wp.getPages', [$this, 'wp_getPages'],
120            ['array', 'integer', 'string', 'string', 'integer'],
[3730]121            'Get an array of all the pages on a blog.');
[2566]122
[3874]123        $this->addCallback('wp.newPage', [$this, 'wp_newPage'],
124            ['integer', 'integer', 'string', 'string', 'struct', 'boolean'],
[3730]125            'Create a new page.');
[2566]126
[3874]127        $this->addCallback('wp.deletePage', [$this, 'wp_deletePage'],
128            ['boolean', 'integer', 'string', 'string', 'integer'],
[3730]129            'Removes a page from the blog.');
[2566]130
[3874]131        $this->addCallback('wp.editPage', [$this, 'wp_editPage'],
132            ['boolean', 'integer', 'integer', 'string', 'string', 'struct', 'boolean'],
[3730]133            'Make changes to a blog page.');
[2566]134
[3874]135        $this->addCallback('wp.getPageList', [$this, 'wp_getPageList'],
136            ['array', 'integer', 'string', 'string'],
[3730]137            'Get an array of all the pages on a blog. Just the minimum details, lighter than wp.getPages.');
[2566]138
[3874]139        $this->addCallback('wp.getAuthors', [$this, 'wp_getAuthors'],
140            ['array', 'integer', 'string', 'string'],
[3730]141            'Get an array of users for the blog.');
[2566]142
[3874]143        $this->addCallback('wp.getCategories', [$this, 'wp_getCategories'],
144            ['array', 'integer', 'string', 'string'],
[3730]145            'Get an array of available categories on a blog.');
[2566]146
[3874]147        $this->addCallback('wp.getTags', [$this, 'wp_getTags'],
148            ['array', 'integer', 'string', 'string'],
[3730]149            'Get list of all tags for the blog.');
[2566]150
[3874]151        $this->addCallback('wp.newCategory', [$this, 'wp_newCategory'],
152            ['integer', 'integer', 'string', 'string', 'struct'],
[3730]153            'Create a new category.');
[2566]154
[3874]155        $this->addCallback('wp.deleteCategory', [$this, 'wp_deleteCategory'],
156            ['boolean', 'integer', 'string', 'string', 'integer'],
[3730]157            'Delete a category with a given ID.');
[2566]158
[3874]159        $this->addCallback('wp.suggestCategories', [$this, 'wp_suggestCategories'],
160            ['array', 'integer', 'string', 'string', 'string', 'integer'],
[3730]161            'Get an array of categories that start with a given string.');
[2566]162
[3874]163        $this->addCallback('wp.uploadFile', [$this, 'wp_uploadFile'],
164            ['struct', 'integer', 'string', 'string', 'struct'],
[3730]165            'Upload a file');
[2566]166
[3874]167        $this->addCallback('wp.getPostStatusList', [$this, 'wp_getPostStatusList'],
168            ['array', 'integer', 'string', 'string'],
[3730]169            'Retrieve all of the post statuses.');
[2566]170
[3874]171        $this->addCallback('wp.getPageStatusList', [$this, 'wp_getPageStatusList'],
172            ['array', 'integer', 'string', 'string'],
[3730]173            'Retrieve all of the pages statuses.');
[2566]174
[3874]175        $this->addCallback('wp.getPageTemplates', [$this, 'wp_getPageTemplates'],
176            ['struct', 'integer', 'string', 'string'],
[3730]177            'Retrieve page templates.');
[2566]178
[3874]179        $this->addCallback('wp.getOptions', [$this, 'wp_getOptions'],
180            ['struct', 'integer', 'string', 'string', 'array'],
[3730]181            'Retrieve blog options');
[2566]182
[3874]183        $this->addCallback('wp.setOptions', [$this, 'wp_setOptions'],
184            ['struct', 'integer', 'string', 'string', 'struct'],
[3730]185            'Update blog options');
[2566]186
[3874]187        $this->addCallback('wp.getComment', [$this, 'wp_getComment'],
188            ['struct', 'integer', 'string', 'string', 'integer'],
[3730]189            "Gets a comment, given it's comment ID.");
[2566]190
[3874]191        $this->addCallback('wp.getCommentCount', [$this, 'wp_getCommentCount'],
192            ['array', 'integer', 'string', 'string', 'integer'],
[3730]193            'Retrieve comment count.');
[2566]194
[3874]195        $this->addCallback('wp.getComments', [$this, 'wp_getComments'],
196            ['array', 'integer', 'string', 'string', 'struct'],
[3730]197            'Gets a set of comments for a given post.');
[2566]198
[3874]199        $this->addCallback('wp.deleteComment', [$this, 'wp_deleteComment'],
200            ['boolean', 'integer', 'string', 'string', 'integer'],
[3730]201            'Delete a comment with given ID.');
[2566]202
[3874]203        $this->addCallback('wp.editComment', [$this, 'wp_editComment'],
204            ['boolean', 'integer', 'string', 'string', 'integer', 'struct'],
[3730]205            'Edit a comment with given ID.');
[2566]206
[3874]207        $this->addCallback('wp.newComment', [$this, 'wp_newComment'],
208            ['integer', 'integer', 'string', 'string', 'integer', 'struct'],
[3730]209            'Create a new comment for a given post ID.');
[2566]210
[3874]211        $this->addCallback('wp.getCommentStatusList', [$this, 'wp_getCommentStatusList'],
212            ['array', 'integer', 'string', 'string'],
[3730]213            'Retrieve all of the comment statuses.');
[2566]214
[3730]215        # Pingback support
[3874]216        $this->addCallback('pingback.ping', [$this, 'pingback_ping'],
217            ['string', 'string', 'string'],
[3730]218            'Notify a link to a post.');
219    }
[2566]220
[3730]221    public function serve($data = false, $encoding = 'UTF-8')
222    {
223        parent::serve(false, $encoding);
224    }
[2566]225
[3730]226    public function call($methodname, $args)
227    {
228        try {
229            $rsp = @parent::call($methodname, $args);
230            $this->debugTrace($methodname, $args, $rsp);
231            return $rsp;
232        } catch (Exception $e) {
[3874]233            $this->debugTrace($methodname, $args, [$e->getMessage(), $e->getCode()]);
[3730]234            throw $e;
235        }
236    }
[2566]237
[3730]238    private function debugTrace($methodname, $args, $rsp)
239    {
240        if (!$this->debug) {
241            return;
242        }
[2566]243
[3730]244        if (($fp = @fopen($this->debug_file, 'a')) !== false) {
245            fwrite($fp, '[' . date('r') . ']' . ' ' . $methodname);
[2566]246
[3730]247            if ($this->trace_args) {
248                fwrite($fp, "\n- args ---\n" . var_export($args, 1));
249            }
[2566]250
[3730]251            if ($this->trace_response) {
252                fwrite($fp, "\n- response ---\n" . var_export($rsp, 1));
253            }
254            fwrite($fp, "\n");
255            fclose($fp);
256        }
257    }
[2566]258
[3730]259    /* Internal methods
260    --------------------------------------------------- */
261    private function setUser($user_id, $pwd)
262    {
263        if (empty($pwd) || $this->core->auth->checkUser($user_id, $pwd) !== true) {
264            throw new Exception('Login error');
265        }
[2566]266
[3730]267        return true;
268    }
[2566]269
[3730]270    private function setBlog($bypass = false)
271    {
272        if (!$this->blog_id) {
273            throw new Exception('No blog ID given.');
274        }
[2566]275
[3730]276        if ($this->blog_loaded) {
277            return true;
278        }
[2566]279
[3730]280        $this->core->setBlog($this->blog_id);
281        $this->blog_loaded = true;
[2566]282
[3730]283        if (!$this->core->blog->id) {
284            $this->core->blog = null;
285            throw new Exception('Blog does not exist.');
286        }
[2566]287
[3730]288        if (!$bypass &&
289            (!$this->core->blog->settings->system->enable_xmlrpc ||
290                !$this->core->auth->check('usage,contentadmin', $this->core->blog->id))) {
291            $this->core->blog = null;
292            throw new Exception('Not enough permissions on this blog.');
293        }
[2566]294
[3730]295        foreach ($this->core->plugins->getModules() as $id => $m) {
296            $this->core->plugins->loadNsFile($id, 'xmlrpc');
297        }
[2566]298
[3730]299        return true;
300    }
[2566]301
[3730]302    private function getPostRS($post_id, $user, $pwd, $post_type = 'post')
303    {
304        $this->setUser($user, $pwd);
305        $this->setBlog();
[3874]306        $rs = $this->core->blog->getPosts([
[3730]307            'post_id'   => (integer) $post_id,
308            'post_type' => $post_type
[3874]309        ]);
[2566]310
[3730]311        if ($rs->isEmpty()) {
312            throw new Exception('This entry does not exist');
313        }
[2566]314
[3730]315        return $rs;
316    }
[2566]317
[3730]318    private function getCatID($cat_url)
319    {
[3874]320        $rs = $this->core->blog->getCategories(['cat_url' => $cat_url]);
[2566]321
[3730]322        return $rs->isEmpty() ? null : $rs->cat_id;
323    }
[2566]324
[3730]325    /* Generic methods
326    --------------------------------------------------- */
[3874]327    private function newPost($blog_id, $user, $pwd, $content, $struct = [], $publish = true)
[3730]328    {
329        $this->setUser($user, $pwd);
330        $this->setBlog();
[2566]331
[3730]332        $title        = !empty($struct['title']) ? $struct['title'] : '';
333        $excerpt      = !empty($struct['mt_excerpt']) ? $struct['mt_excerpt'] : '';
334        $description  = !empty($struct['description']) ? $struct['description'] : null;
335        $dateCreated  = !empty($struct['dateCreated']) ? $struct['dateCreated'] : null;
336        $open_comment = isset($struct['mt_allow_comments']) ? $struct['mt_allow_comments'] : 1;
337        $open_tb      = isset($struct['mt_allow_pings']) ? $struct['mt_allow_pings'] : 1;
[2566]338
[3730]339        if ($description !== null) {
340            $content = $description;
341        }
[2566]342
[3730]343        if (!$title) {
344            $title = text::cutString(html::clean($content), 25) . '...';
345        }
[2566]346
[3730]347        $excerpt_xhtml = $this->core->callFormater('xhtml', $excerpt);
348        $content_xhtml = $this->core->callFormater('xhtml', $content);
[2566]349
[3730]350        if (empty($content)) {
351            throw new Exception('Cannot create an empty entry');
352        }
[2566]353
[3730]354        $cur = $this->core->con->openCursor($this->core->prefix . 'post');
[2566]355
[3730]356        $cur->user_id            = $this->core->auth->userID();
357        $cur->post_lang          = $this->core->auth->getInfo('user_lang');
358        $cur->post_title         = trim($title);
359        $cur->post_content       = $content;
360        $cur->post_excerpt       = $excerpt;
361        $cur->post_content_xhtml = $content_xhtml;
362        $cur->post_excerpt_xhtml = $excerpt_xhtml;
363        $cur->post_open_comment  = (integer) ($open_comment == 1);
364        $cur->post_open_tb       = (integer) ($open_tb == 1);
365        $cur->post_status        = (integer) $publish;
366        $cur->post_format        = 'xhtml';
[2566]367
[3730]368        if ($dateCreated) {
369            if ($dateCreated instanceof xmlrpcDate) {
370                $cur->post_dt = date('Y-m-d H:i:00', $dateCreated->getTimestamp());
371            } elseif (is_string($dateCreated) && @strtotime($dateCreated)) {
372                $cur->post_dt = date('Y-m-d H:i:00', strtotime($dateCreated));
373            }
374        }
[2566]375
[3730]376        # Categories in an array
377        if (isset($struct['categories']) && is_array($struct['categories'])) {
378            $categories = $struct['categories'];
379            $cat_id     = !empty($categories[0]) ? $categories[0] : null;
[2566]380
[3730]381            $cur->cat_id = $this->getCatID($cat_id);
382        }
[2566]383
[3730]384        if (isset($struct['wp_slug'])) {
385            $cur->post_url = $struct['wp_slug'];
386        }
[2566]387
[3730]388        if (isset($struct['wp_password'])) {
389            $cur->post_password = $struct['wp_password'];
390        }
[2566]391
[3730]392        $cur->post_type = 'post';
393        if (!empty($struct['post_type'])) {
394            $cur->post_type = $struct['post_type'];
395        }
[2566]396
[3730]397        if ($cur->post_type == 'post') {
398            # --BEHAVIOR-- xmlrpcBeforeNewPost
399            $this->core->callBehavior('xmlrpcBeforeNewPost', $this, $cur, $content, $struct, $publish);
[2566]400
[3730]401            $post_id = $this->core->blog->addPost($cur);
[2566]402
[3730]403            # --BEHAVIOR-- xmlrpcAfterNewPost
404            $this->core->callBehavior('xmlrpcAfterNewPost', $this, $post_id, $cur, $content, $struct, $publish);
405        } elseif ($cur->post_type == 'page') {
406            if (isset($struct['wp_page_order'])) {
407                $cur->post_position = (integer) $struct['wp_page_order'];
408            }
[2566]409
[3730]410            $this->core->blog->settings->system->post_url_format = '{t}';
[2566]411
[3730]412            $post_id = $this->core->blog->addPost($cur);
413        } else {
414            throw new Exception('Invalid post type', 401);
415        }
[2566]416
[3730]417        return (string) $post_id;
418    }
[2566]419
[3874]420    private function editPost($post_id, $user, $pwd, $content, $struct = [], $publish = true)
[3730]421    {
422        $post_id = (integer) $post_id;
[2566]423
[3730]424        $post_type = 'post';
425        if (!empty($struct['post_type'])) {
426            $post_type = $struct['post_type'];
427        }
[2566]428
[3730]429        $post = $this->getPostRS($post_id, $user, $pwd, $post_type);
[2566]430
[3730]431        $title        = (!empty($struct['title'])) ? $struct['title'] : '';
432        $excerpt      = (!empty($struct['mt_excerpt'])) ? $struct['mt_excerpt'] : '';
433        $description  = (!empty($struct['description'])) ? $struct['description'] : null;
434        $dateCreated  = !empty($struct['dateCreated']) ? $struct['dateCreated'] : null;
435        $open_comment = (isset($struct['mt_allow_comments'])) ? $struct['mt_allow_comments'] : 1;
436        $open_tb      = (isset($struct['mt_allow_pings'])) ? $struct['mt_allow_pings'] : 1;
[2566]437
[3730]438        if ($description !== null) {
439            $content = $description;
440        }
[2566]441
[3730]442        if (!$title) {
443            $title = text::cutString(html::clean($content), 25) . '...';
444        }
[2566]445
[3730]446        $excerpt_xhtml = $this->core->callFormater('xhtml', $excerpt);
447        $content_xhtml = $this->core->callFormater('xhtml', $content);
[2566]448
[3730]449        if (empty($content)) {
450            throw new Exception('Cannot create an empty entry');
451        }
[2566]452
[3730]453        $cur = $this->core->con->openCursor($this->core->prefix . 'post');
[2566]454
[3730]455        $cur->post_type          = $post_type;
456        $cur->post_title         = trim($title);
457        $cur->post_content       = $content;
458        $cur->post_excerpt       = $excerpt;
459        $cur->post_content_xhtml = $content_xhtml;
460        $cur->post_excerpt_xhtml = $excerpt_xhtml;
461        $cur->post_open_comment  = (integer) ($open_comment == 1);
462        $cur->post_open_tb       = (integer) ($open_tb == 1);
463        $cur->post_status        = (integer) $publish;
464        $cur->post_format        = 'xhtml';
465        $cur->post_url           = $post->post_url;
[2566]466
[3730]467        if ($dateCreated) {
468            if ($dateCreated instanceof xmlrpcDate) {
469                $cur->post_dt = date('Y-m-d H:i:00', $dateCreated->getTimestamp());
470            } elseif (is_string($dateCreated) && @strtotime($dateCreated)) {
471                $cur->post_dt = date('Y-m-d H:i:00', strtotime($dateCreated));
472            }
473        } else {
474            $cur->post_dt = $post->post_dt;
475        }
[2566]476
[3730]477        # Categories in an array
478        if (isset($struct['categories']) && is_array($struct['categories'])) {
479            $categories = $struct['categories'];
480            $cat_id     = !empty($categories[0]) ? $categories[0] : null;
[2566]481
[3730]482            $cur->cat_id = $this->getCatID($cat_id);
483        }
[2566]484
[3730]485        if (isset($struct['wp_slug'])) {
486            $cur->post_url = $struct['wp_slug'];
487        }
[2566]488
[3730]489        if (isset($struct['wp_password'])) {
490            $cur->post_password = $struct['wp_password'];
491        }
[2566]492
[3730]493        if ($cur->post_type == 'post') {
494            # --BEHAVIOR-- xmlrpcBeforeEditPost
495            $this->core->callBehavior('xmlrpcBeforeEditPost', $this, $post_id, $cur, $content, $struct, $publish);
[2566]496
[3730]497            $this->core->blog->updPost($post_id, $cur);
[2566]498
[3730]499            # --BEHAVIOR-- xmlrpcAfterEditPost
500            $this->core->callBehavior('xmlrpcAfterEditPost', $this, $post_id, $cur, $content, $struct, $publish);
501        } elseif ($cur->post_type == 'page') {
502            if (isset($struct['wp_page_order'])) {
503                $cur->post_position = (integer) $struct['wp_page_order'];
504            }
[2566]505
[3730]506            $this->core->blog->settings->system->post_url_format = '{t}';
[2566]507
[3730]508            $this->core->blog->updPost($post_id, $cur);
509        } else {
510            throw new Exception('Invalid post type', 401);
511        }
[2566]512
[3730]513        return true;
514    }
[2566]515
[3730]516    private function getPost($post_id, $user, $pwd, $type = 'mw')
517    {
518        $post_id = (integer) $post_id;
[2566]519
[3730]520        $post = $this->getPostRS($post_id, $user, $pwd);
[2566]521
[3730]522        $res = new ArrayObject();
[2566]523
[3730]524        $res['dateCreated'] = new xmlrpcDate($post->getTS());
525        $res['userid']      = $post->user_id;
526        $res['postid']      = $post->post_id;
[2566]527
[3730]528        if ($post->cat_id) {
[3874]529            $res['categories'] = [$post->cat_url];
[3730]530        }
[2566]531
[3730]532        if ($type == 'blogger') {
533            $res['content'] = $post->post_content_xhtml;
534        }
[2566]535
[3730]536        if ($type == 'mt' || $type == 'mw') {
537            $res['title'] = $post->post_title;
538        }
[2566]539
[3730]540        if ($type == 'mw') {
541            $res['description']       = $post->post_content_xhtml;
542            $res['link']              = $res['permaLink']              = $post->getURL();
543            $res['mt_excerpt']        = $post->post_excerpt_xhtml;
544            $res['mt_text_more']      = '';
545            $res['mt_allow_comments'] = (integer) $post->post_open_comment;
546            $res['mt_allow_pings']    = (integer) $post->post_open_tb;
547            $res['mt_convert_breaks'] = '';
548            $res['mt_keywords']       = '';
549        }
[2566]550
[3730]551        # --BEHAVIOR-- xmlrpcGetPostInfo
[3874]552        $this->core->callBehavior('xmlrpcGetPostInfo', $this, $type, [&$res]);
[2566]553
[3730]554        return $res;
555    }
[2566]556
[3730]557    private function deletePost($post_id, $user, $pwd)
558    {
559        $post_id = (integer) $post_id;
[2566]560
[3730]561        $this->getPostRS($post_id, $user, $pwd);
562        $this->core->blog->delPost($post_id);
[2566]563
[3730]564        return true;
565    }
[2566]566
[3730]567    private function getRecentPosts($blog_id, $user, $pwd, $nb_post, $type = 'mw')
568    {
569        $this->setUser($user, $pwd);
570        $this->setBlog();
[2566]571
[3730]572        $nb_post = (integer) $nb_post;
[2566]573
[3730]574        if ($nb_post > 50) {
575            throw new Exception('Cannot retrieve more than 50 entries');
576        }
[2566]577
[3874]578        $params          = [];
[3730]579        $params['limit'] = $nb_post;
[2566]580
[3730]581        $posts = $this->core->blog->getPosts($params);
[2566]582
[3874]583        $res = [];
[3730]584        while ($posts->fetch()) {
[3874]585            $tres = [];
[2566]586
[3730]587            $tres['dateCreated'] = new xmlrpcDate($posts->getTS());
588            $tres['userid']      = $posts->user_id;
589            $tres['postid']      = $posts->post_id;
[2566]590
[3730]591            if ($posts->cat_id) {
[3874]592                $tres['categories'] = [$posts->cat_url];
[3730]593            }
[2566]594
[3730]595            if ($type == 'blogger') {
596                $tres['content'] = $posts->post_content_xhtml;
597            }
[2566]598
[3730]599            if ($type == 'mt' || $type == 'mw') {
600                $tres['title'] = $posts->post_title;
601            }
[2566]602
[3730]603            if ($type == 'mw') {
604                $tres['description']       = $posts->post_content_xhtml;
605                $tres['link']              = $tres['permaLink']              = $posts->getURL();
606                $tres['mt_excerpt']        = $posts->post_excerpt_xhtml;
607                $tres['mt_text_more']      = '';
608                $tres['mt_allow_comments'] = (integer) $posts->post_open_comment;
609                $tres['mt_allow_pings']    = (integer) $posts->post_open_tb;
610                $tres['mt_convert_breaks'] = '';
611                $tres['mt_keywords']       = '';
612            }
[2566]613
[3730]614            # --BEHAVIOR-- xmlrpcGetPostInfo
[3874]615            $this->core->callBehavior('xmlrpcGetPostInfo', $this, $type, [&$tres]);
[2566]616
[3730]617            $res[] = $tres;
618        }
[2566]619
[3730]620        return $res;
621    }
[2566]622
[3730]623    private function getUserBlogs($user, $pwd)
624    {
625        $this->setUser($user, $pwd);
626        $this->setBlog();
[2566]627
[3874]628        return [[
[3730]629            'url'      => $this->core->blog->url,
630            'blogid'   => '1',
631            'blogName' => $this->core->blog->name
[3874]632        ]];
[3730]633    }
[2566]634
[3730]635    private function getUserInfo($user, $pwd)
636    {
637        $this->setUser($user, $pwd);
[2566]638
[3874]639        return [
[3730]640            'userid'    => $this->core->auth->userID(),
641            'firstname' => $this->core->auth->getInfo('user_firstname'),
642            'lastname'  => $this->core->auth->getInfo('user_name'),
643            'nickname'  => $this->core->auth->getInfo('user_displayname'),
644            'email'     => $this->core->auth->getInfo('user_email'),
645            'url'       => $this->core->auth->getInfo('user_url')
[3874]646        ];
[3730]647    }
[2566]648
[3730]649    private function getCategories($blog_id, $user, $pwd)
650    {
651        $this->setUser($user, $pwd);
652        $this->setBlog();
653        $rs = $this->core->blog->getCategories();
[2566]654
[3874]655        $res = [];
[2566]656
[3730]657        $l     = $rs->level;
[3874]658        $stack = ['', $rs->cat_url];
[2566]659
[3730]660        while ($rs->fetch()) {
661            $d = $rs->level - $l;
662            if ($d == 0) {
663                array_pop($stack);
664                $parent = end($stack);
665            } elseif ($d > 0) {
666                $parent = end($stack);
667            } elseif ($d < 0) {
668                $D = abs($d);
669                for ($i = 0; $i <= $D; $i++) {
670                    array_pop($stack);
671                }
672                $parent = end($stack);
673            }
[2566]674
[3874]675            $res[] = [
[3730]676                'categoryId'   => $rs->cat_url,
677                'parentId'     => $parent,
678                'description'  => $rs->cat_title,
679                'categoryName' => $rs->cat_url,
680                'htmlUrl'      => $this->core->blog->url .
681                $this->core->url->getURLFor('category', $rs->cat_url),
682                'rssUrl'       => $this->core->blog->url .
683                $this->core->url->getURLFor('feed', 'category/' . $rs->cat_url . '/rss2')
[3874]684            ];
[2566]685
[3730]686            $stack[] = $rs->cat_url;
687            $l       = $rs->level;
688        }
[2566]689
[3730]690        return $res;
691    }
[2566]692
[3730]693    private function getPostCategories($post_id, $user, $pwd)
694    {
695        $post_id = (integer) $post_id;
[2566]696
[3730]697        $post = $this->getPostRS($post_id, $user, $pwd);
[2566]698
[3874]699        return [
700            [
[3730]701                'categoryName' => $post->cat_url,
702                'categoryId'   => (string) $post->cat_url,
703                'isPrimary'    => true
[3874]704            ]
705        ];
[3730]706    }
[2566]707
[3730]708    private function setPostCategories($post_id, $user, $pwd, $categories)
709    {
710        $post_id = (integer) $post_id;
[2566]711
[3730]712        $post = $this->getPostRS($post_id, $user, $pwd);
[2566]713
[3730]714        $cat_id = (!empty($categories[0]['categoryId'])) ? $categories[0]['categoryId'] : null;
[2566]715
[3730]716        foreach ($categories as $v) {
717            if (isset($v['isPrimary']) && $v['isPrimary']) {
718                $cat_id = $v['categoryId'];
719                break;
720            }
721        }
[2566]722
[3730]723        # w.bloggar sends -1 for no category.
724        if ($cat_id == -1) {
725            $cat_id = null;
726        }
[2566]727
[3730]728        if ($cat_id) {
729            $cat_id = $this->getCatID($cat_id);
730        }
[2566]731
[3730]732        $this->core->blog->updPostCategory($post_id, (integer) $cat_id);
[2566]733
[3730]734        return true;
735    }
[2566]736
[3730]737    private function publishPost($post_id, $user, $pwd)
738    {
739        $post_id = (integer) $post_id;
[2566]740
[3730]741        $this->getPostRS($post_id, $user, $pwd);
[2566]742
[3730]743        # --BEHAVIOR-- xmlrpcBeforePublishPost
744        $this->core->callBehavior('xmlrpcBeforePublishPost', $this, $post_id);
[2566]745
[3730]746        $this->core->blog->updPostStatus($post_id, 1);
[2566]747
[3730]748        # --BEHAVIOR-- xmlrpcAfterPublishPost
749        $this->core->callBehavior('xmlrpcAfterPublishPost', $this, $post_id);
[2566]750
[3730]751        return true;
752    }
[2566]753
[3730]754    private function newMediaObject($blog_id, $user, $pwd, $file)
755    {
756        if (empty($file['name'])) {
757            throw new Exception('No file name');
758        }
[2566]759
[3730]760        if (empty($file['bits'])) {
761            throw new Exception('No file content');
762        }
[2566]763
[3730]764        $file_name = $file['name'];
765        $file_bits = $file['bits'];
[2566]766
[3730]767        $this->setUser($user, $pwd);
768        $this->setBlog();
[2566]769
[3730]770        $media = new dcMedia($this->core);
[2566]771
[3730]772        $dir_name  = path::clean(dirname($file_name));
773        $file_name = basename($file_name);
[2566]774
[3730]775        $dir_name = preg_replace('!^/!', '', $dir_name);
776        if ($dir_name != '') {
777            $dir = explode('/', $dir_name);
778            $cwd = './';
779            foreach ($dir as $v) {
780                $v = files::tidyFileName($v);
781                $cwd .= $v . '/';
782                $media->makeDir($v);
783                $media->chdir($cwd);
784            }
785        }
[2566]786
[3730]787        $media_id = $media->uploadBits($file_name, $file_bits);
[2566]788
[3730]789        $f = $media->getFile($media_id);
[3874]790        return [
[3730]791            'file' => $file_name,
792            'url'  => $f->file_url,
793            'type' => files::getMimeType($file_name)
[3874]794        ];
[3730]795    }
[2566]796
[3730]797    private function translateWpStatus($s)
798    {
[3874]799        $status = [
[3730]800            'draft'     => -2,
801            'pending'   => -2,
802            'private'   => 0,
803            'publish'   => 1,
804            'scheduled' => -1
[3874]805        ];
[2566]806
[3730]807        if (is_int($s)) {
808            $status = array_flip($status);
809            return isset($status[$s]) ? $status[$s] : $status[-2];
810        } else {
811            return isset($status[$s]) ? $status[$s] : $status['pending'];
812        }
813    }
[2566]814
[3730]815    private function translateWpCommentstatus($s)
816    {
[3874]817        $status = [
[3730]818            'hold'    => -1,
819            'approve' => 0,
820            'spam'    => -2
[3874]821        ];
[2566]822
[3730]823        if (is_int($s)) {
824            $status = array_flip($status);
825            return isset($status[$s]) ? $status[$s] : $status[0];
826        } else {
827            return isset($status[$s]) ? $status[$s] : $status['approve'];
828        }
829    }
[2566]830
[3874]831    private function translateWpOptions($options = [])
[3730]832    {
833        $timezone = 0;
834        if ($this->core->blog->settings->system->blog_timezone) {
835            $timezone = dt::getTimeOffset($this->core->blog->settings->system->blog_timezone) / 3600;
836        }
[2566]837
[3874]838        $res = [
839            'software_name'    => [
[3730]840                'desc'     => 'Software Name',
841                'readonly' => true,
842                'value'    => 'Dotclear'
[3874]843            ],
844            'software_version' => [
[3730]845                'desc'     => 'Software Version',
846                'readonly' => true,
847                'value'    => DC_VERSION
[3874]848            ],
849            'blog_url'         => [
[3730]850                'desc'     => 'Blog URL',
851                'readonly' => true,
852                'value'    => $this->core->blog->url
[3874]853            ],
854            'time_zone'        => [
[3730]855                'desc'     => 'Time Zone',
856                'readonly' => true,
857                'value'    => (string) $timezone
[3874]858            ],
859            'blog_title'       => [
[3730]860                'desc'     => 'Blog Title',
861                'readonly' => false,
862                'value'    => $this->core->blog->name
[3874]863            ],
864            'blog_tagline'     => [
[3730]865                'desc'     => 'Blog Tagline',
866                'readonly' => false,
867                'value'    => $this->core->blog->desc
[3874]868            ],
869            'date_format'      => [
[3730]870                'desc'     => 'Date Format',
871                'readonly' => false,
872                'value'    => $this->core->blog->settings->system->date_format
[3874]873            ],
874            'time_format'      => [
[3730]875                'desc'     => 'Time Format',
876                'readonly' => false,
877                'value'    => $this->core->blog->settings->system->time_format
[3874]878            ]
879        ];
[2566]880
[3730]881        if (!empty($options)) {
[3874]882            $r = [];
[3730]883            foreach ($options as $v) {
884                if (isset($res[$v])) {
885                    $r[$v] = $res[$v];
886                }
887            }
888            return $r;
889        }
[2566]890
[3730]891        return $res;
892    }
[2566]893
[3730]894    private function getPostStatusList($blog_id, $user, $pwd)
895    {
896        $this->setUser($user, $pwd);
897        $this->setBlog();
[2566]898
[3874]899        return [
[3730]900            'draft'     => 'Draft',
901            'pending'   => 'Pending Review',
902            'private'   => 'Private',
903            'publish'   => 'Published',
904            'scheduled' => 'Scheduled'
[3874]905        ];
[3730]906    }
[2566]907
[3730]908    private function getPageStatusList($blog_id, $user, $pwd)
909    {
910        $this->setUser($user, $pwd);
911        $this->setBlog();
912        $this->checkPagesPermission();
[2566]913
[3874]914        return [
[3730]915            'draft'     => 'Draft',
916            'private'   => 'Private',
917            'published' => 'Published',
918            'scheduled' => 'Scheduled'
[3874]919        ];
[3730]920    }
[2566]921
[3730]922    private function checkPagesPermission()
923    {
924        if (!$this->core->plugins->moduleExists('pages')) {
925            throw new Exception('Pages management is not available on this blog.');
926        }
[2566]927
[3730]928        if (!$this->core->auth->check('pages,contentadmin', $this->core->blog->id)) {
929            throw new Exception('Not enough permissions to edit pages.', 401);
930        }
931    }
[2566]932
[3730]933    private function getPages($blog_id, $user, $pwd, $limit = null, $id = null)
934    {
935        $this->setUser($user, $pwd);
936        $this->setBlog();
937        $this->checkPagesPermission();
[2566]938
[3874]939        $params = [
[3730]940            'post_type' => 'page',
941            'order'     => 'post_position ASC, post_title ASC'
[3874]942        ];
[2566]943
[3730]944        if ($id) {
945            $params['post_id'] = (integer) $id;
946        }
947        if ($limit) {
948            $params['limit'] = $limit;
949        }
[2566]950
[3730]951        $posts = $this->core->blog->getPosts($params);
[2566]952
[3874]953        $res = [];
[3730]954        while ($posts->fetch()) {
[3874]955            $tres = [
[3730]956                "dateCreated"            => new xmlrpcDate($posts->getTS()),
957                "userid"                 => $posts->user_id,
958                "page_id"                => $posts->post_id,
959                "page_status"            => $this->translateWpStatus((integer) $posts->post_status),
960                "description"            => $posts->post_content_xhtml,
961                "title"                  => $posts->post_title,
962                "link"                   => $posts->getURL(),
963                "permaLink"              => $posts->getURL(),
[3874]964                "categories"             => [],
[3730]965                "excerpt"                => $posts->post_excerpt_xhtml,
966                "text_more"              => '',
967                "mt_allow_comments"      => (integer) $posts->post_open_comment,
968                "mt_allow_pings"         => (integer) $posts->post_open_tb,
969                "wp_slug"                => $posts->post_url,
970                "wp_password"            => $posts->post_password,
971                "wp_author"              => $posts->getAuthorCN(),
972                "wp_page_parent_id"      => 0,
973                "wp_page_parent_title"   => '',
974                "wp_page_order"          => $posts->post_position,
975                "wp_author_id"           => $posts->user_id,
976                "wp_author_display_name" => $posts->getAuthorCN(),
977                "date_created_gmt"       => new xmlrpcDate(dt::iso8601($posts->getTS(), $posts->post_tz)),
[3874]978                "custom_fields"          => [],
[3730]979                "wp_page_template"       => 'default'
[3874]980            ];
[2566]981
[3730]982            # --BEHAVIOR-- xmlrpcGetPageInfo
[3874]983            $this->core->callBehavior('xmlrpcGetPageInfo', $this, [&$tres]);
[2566]984
[3730]985            $res[] = $tres;
986        }
[2566]987
[3730]988        return $res;
989    }
[2566]990
[3730]991    private function newPage($blog_id, $user, $pwd, $struct, $publish)
992    {
993        $this->setUser($user, $pwd);
994        $this->setBlog();
995        $this->checkPagesPermission();
[2566]996
[3730]997        $struct['post_type'] = 'page';
[2566]998
[3730]999        return $this->newPost($blog_id, $user, $pwd, null, $struct, $publish);
1000    }
[2566]1001
[3730]1002    private function editPage($page_id, $user, $pwd, $struct, $publish)
1003    {
1004        $this->setUser($user, $pwd);
1005        $this->setBlog();
1006        $this->checkPagesPermission();
[2566]1007
[3730]1008        $struct['post_type'] = 'page';
[2566]1009
[3730]1010        return $this->editPost($page_id, $user, $pwd, null, $struct, $publish);
1011    }
[2566]1012
[3730]1013    private function deletePage($page_id, $user, $pwd)
1014    {
1015        $this->setUser($user, $pwd);
1016        $this->setBlog();
1017        $this->checkPagesPermission();
[2566]1018
[3730]1019        $page_id = (integer) $page_id;
[2566]1020
[3730]1021        $this->getPostRS($page_id, $user, $pwd, 'page');
1022        $this->core->blog->delPost($page_id);
[2566]1023
[3730]1024        return true;
1025    }
[2566]1026
[3730]1027    private function getAuthors($user, $pwd)
1028    {
1029        $this->setUser($user, $pwd);
1030        $this->setBlog();
[2566]1031
[3730]1032        $rs  = $this->core->getBlogPermissions($this->core->blog->id);
[3874]1033        $res = [];
[2566]1034
[3730]1035        foreach ($rs as $k => $v) {
[3874]1036            $res[] = [
[3730]1037                'user_id'      => $k,
1038                'user_login'   => $k,
1039                'display_name' => dcUtils::getUserCN($k, $v['name'], $v['firstname'], $v['displayname'])
[3874]1040            ];
[3730]1041        }
1042        return $res;
1043    }
[2566]1044
[3730]1045    private function getTags($user, $pwd)
1046    {
1047        $this->setUser($user, $pwd);
1048        $this->setBlog();
[2566]1049
[3730]1050        $tags = $this->core->meta->getMeta('tag');
1051        $tags->sort('meta_id_lower', 'asc');
[2566]1052
[3874]1053        $res = [];
[3730]1054        $url = $this->core->blog->url .
1055        $this->core->url->getURLFor('tag', '%s');
1056        $f_url = $this->core->blog->url .
1057        $this->core->url->getURLFor('tag_feed', '%s');
1058        while ($tags->fetch()) {
[3874]1059            $res[] = [
[3730]1060                'tag_id'   => $tags->meta_id,
1061                'name'     => $tags->meta_id,
1062                'count'    => $tags->count,
1063                'slug'     => $tags->meta_id,
1064                'html_url' => sprintf($url, $tags->meta_id),
1065                'rss_url'  => sprintf($f_url, $tags->meta_id)
[3874]1066            ];
[3730]1067        }
1068        return $res;
1069    }
[2566]1070
[3730]1071    private function newCategory($user, $pwd, $struct)
1072    {
1073        $this->setUser($user, $pwd);
1074        $this->setBlog();
[2566]1075
[3730]1076        if (empty($struct['name'])) {
1077            throw new Exception('You mus give a category name.');
1078        }
[2566]1079
[3730]1080        $cur            = $this->core->con->openCursor($this->core->prefix . 'category');
1081        $cur->cat_title = $struct['name'];
[2566]1082
[3730]1083        if (!empty($struct['slug'])) {
1084            $cur->cat_url = $struct['slug'];
1085        }
1086        if (!empty($struct['category_description'])) {
1087            $cur->cat_desc = $struct['category_description'];
1088            if (html::clean($cur->cat_desc) == $cur->cat_desc) {
1089                $cur->cat_desc = '<p>' . $cur->cat_desc . '</p>';
1090            }
1091        }
[2566]1092
[3730]1093        $parent = !empty($struct['category_parent']) ? (integer) $struct['category_parent'] : 0;
[2566]1094
[3730]1095        $id = $this->core->blog->addCategory($cur, $parent);
1096        $rs = $this->core->blog->getCategory($id);
1097        return $rs->cat_url;
1098    }
[2566]1099
[3730]1100    private function deleteCategory($user, $pwd, $cat_id)
1101    {
1102        $this->setUser($user, $pwd);
1103        $this->setBlog();
[2566]1104
[3874]1105        $c = $this->core->blog->getCategories(['cat_url' => $cat_id]);
[3730]1106        if ($c->isEmpty()) {
1107            throw new Exception(__('This category does not exist.'));
1108        }
1109        $cat_id = $c->cat_id;
1110        unset($c);
[2566]1111
[3730]1112        $this->core->blog->delCategory((integer) $cat_id);
1113        return true;
1114    }
[2566]1115
[3730]1116    private function searchCategories($user, $pwd, $category, $limit)
1117    {
1118        $this->setUser($user, $pwd);
1119        $this->setBlog();
[2566]1120
[3730]1121        $strReq = 'SELECT cat_id, cat_title, cat_url ' .
1122        'FROM ' . $this->core->prefix . 'category ' .
1123        "WHERE blog_id = '" . $this->core->con->escape($this->core->blog->id) . "' " .
1124        "AND LOWER(cat_title) LIKE LOWER('%" . $this->core->con->escape($category) . "%') " .
1125            ($limit > 0 ? $this->core->con->limit($limit) : '');
[2566]1126
[3730]1127        $rs = $this->core->con->select($strReq);
[2566]1128
[3874]1129        $res = [];
[3730]1130        while ($rs->fetch()) {
[3874]1131            $res[] = [
[3730]1132                'category_id'   => $rs->cat_url,
1133                'category_name' => $rs->cat_url
[3874]1134            ];
[3730]1135        }
1136        return $res;
1137    }
[2566]1138
[3730]1139    private function countComments($user, $pwd, $post_id)
1140    {
1141        $this->setUser($user, $pwd);
1142        $this->setBlog();
[2566]1143
[3874]1144        $res = [
[3730]1145            'approved'            => 0,
1146            'awaiting_moderation' => 0,
1147            'spam'                => 0,
1148            'total'               => 0
[3874]1149        ];
1150        $rs = $this->core->blog->getComments(['post_id' => $post_id]);
[2566]1151
[3730]1152        while ($rs->fetch()) {
1153            $res['total']++;
1154            if ($rs->comment_status == 1) {
1155                $res['approved']++;
1156            } elseif ($rs->comment_status == -2) {
1157                $res['spam']++;
1158            } else {
1159                $res['awaiting_moderation']++;
1160            }
1161        }
1162        return $res;
1163    }
[2566]1164
[3730]1165    private function getComments($user, $pwd, $struct, $id = null)
1166    {
1167        $this->setUser($user, $pwd);
1168        $this->setBlog();
[2566]1169
[3874]1170        $params = [];
[2566]1171
[3730]1172        if (!empty($struct['status'])) {
1173            $params['comment_status'] = $this->translateWpCommentstatus($struct['status']);
1174        }
[2566]1175
[3730]1176        if (!empty($struct['post_id'])) {
1177            $params['post_id'] = (integer) $struct['post_id'];
1178        }
[2566]1179
[3730]1180        if (isset($id)) {
1181            $params['comment_id'] = $id;
1182        }
[2566]1183
[3730]1184        $offset          = !empty($struct['offset']) ? (integer) $struct['offset'] : 0;
1185        $limit           = !empty($struct['number']) ? (integer) $struct['number'] : 10;
[3874]1186        $params['limit'] = [$offset, $limit];
[2566]1187
[3730]1188        $rs  = $this->core->blog->getComments($params);
[3874]1189        $res = [];
[3730]1190        while ($rs->fetch()) {
[3874]1191            $res[] = [
[3730]1192                'date_created_gmt' => new xmlrpcDate($rs->getTS()),
1193                'user_id'          => $rs->user_id,
1194                'comment_id'       => $rs->comment_id,
1195                'parent'           => 0,
1196                'status'           => $this->translateWpCommentstatus((integer) $rs->comment_status),
1197                'content'          => $rs->comment_content,
1198                'link'             => $rs->getPostURL() . '#c' . $rs->comment_id,
1199                'post_id'          => $rs->post_id,
1200                'post_title'       => $rs->post_title,
1201                'author'           => $rs->comment_author,
1202                'author_url'       => $rs->comment_site,
1203                'author_email'     => $rs->comment_email,
1204                'author_ip'        => $rs->comment_ip
[3874]1205            ];
[3730]1206        }
1207        return $res;
1208    }
[2566]1209
[3730]1210    private function addComment($user, $pwd, $post_id, $struct)
1211    {
1212        $this->setUser($user, $pwd);
1213        $this->setBlog();
[2566]1214
[3730]1215        if (empty($struct['content'])) {
1216            throw new Exception('Sorry, you cannot post an empty comment', 401);
1217        }
[2566]1218
[3730]1219        if (is_numeric($post_id)) {
1220            $p['post_id'] = $post_id;
1221        } else {
1222            $p['post_url'] = $post_id;
1223        }
1224        $rs = $this->core->blog->getPosts($p);
1225        if ($rs->isEmpty()) {
1226            throw new Exception('Sorry, no such post.', 404);
1227        }
[2566]1228
[3730]1229        $cur = $this->core->con->openCursor($this->core->prefix . 'comment');
[2566]1230
[3730]1231        $cur->comment_author = $this->core->auth->getInfo('user_cn');
1232        $cur->comment_email  = $this->core->auth->getInfo('user_email');
1233        $cur->comment_site   = $this->core->auth->getInfo('user_url');
[2566]1234
[3730]1235        $cur->comment_content = $struct['content'];
1236        $cur->post_id         = (integer) $post_id;
[2566]1237
[3730]1238        $id = $this->core->blog->addComment($cur);
1239        return $id;
1240    }
[2566]1241
[3730]1242    private function updComment($user, $pwd, $comment_id, $struct)
1243    {
1244        $this->setUser($user, $pwd);
1245        $this->setBlog();
[2566]1246
[3730]1247        $cur = $this->core->con->openCursor($this->core->prefix . 'comment');
[2566]1248
[3730]1249        if (isset($struct['status'])) {
1250            $cur->comment_status = $this->translateWpCommentstatus($struct['status']);
1251        }
[2566]1252
[3730]1253        if (isset($struct['date_created_gmt'])) {
1254            if ($struct['date_created_gmt'] instanceof xmlrpcDate) {
1255                $cur->comment_dt = date('Y-m-d H:i:00', $struct['date_created_gmt']->getTimestamp());
1256            } elseif (is_string($struct['date_created_gmt']) && @strtotime($struct['date_created_gmt'])) {
1257                $cur->comment_dt = date('Y-m-d H:i:00', strtotime($struct['date_created_gmt']));
1258            }
1259            $cur->comment_dt = $struct['date_created_gmt'];
1260        }
[2566]1261
[3730]1262        if (isset($struct['content'])) {
1263            $cur->comment_content = $struct['content'];
1264        }
[2566]1265
[3730]1266        if (isset($struct['author'])) {
1267            $cur->comment_author = $struct['author'];
1268        }
[2566]1269
[3730]1270        if (isset($struct['author_url'])) {
1271            $cur->comment_site = $struct['author_url'];
1272        }
[2566]1273
[3730]1274        if (isset($struct['author_email'])) {
1275            $cur->comment_email = $struct['author_email'];
1276        }
[2566]1277
[3730]1278        $this->core->blog->updComment($comment_id, $cur);
1279        return true;
1280    }
[2566]1281
[3730]1282    private function delComment($user, $pwd, $comment_id)
1283    {
1284        $this->setUser($user, $pwd);
1285        $this->setBlog();
[2566]1286
[3730]1287        $this->core->blog->delComment($comment_id);
1288        return true;
1289    }
[2566]1290
[3730]1291    /* Blogger methods
1292    --------------------------------------------------- */
1293    public function blogger_newPost($appkey, $blogid, $username, $password, $content, $publish)
1294    {
[3874]1295        return $this->newPost($blogid, $username, $password, $content, [], $publish);
[3730]1296    }
[2566]1297
[3730]1298    public function blogger_editPost($appkey, $postid, $username, $password, $content, $publish)
1299    {
[3874]1300        return $this->editPost($postid, $username, $password, $content, [], $publish);
[3730]1301    }
[2566]1302
[3730]1303    public function blogger_getPost($appkey, $postid, $username, $password)
1304    {
1305        return $this->getPost($postid, $username, $password, 'blogger');
1306    }
[2566]1307
[3730]1308    public function blogger_deletePost($appkey, $postid, $username, $password, $publish)
1309    {
1310        return $this->deletePost($postid, $username, $password);
1311    }
[2566]1312
[3730]1313    public function blogger_getRecentPosts($appkey, $blogid, $username, $password, $numberOfPosts)
1314    {
1315        return $this->getRecentPosts($blogid, $username, $password, $numberOfPosts, 'blogger');
1316    }
[2566]1317
[3730]1318    public function blogger_getUserBlogs($appkey, $username, $password)
1319    {
1320        return $this->getUserBlogs($username, $password);
1321    }
[2566]1322
[3730]1323    public function blogger_getUserInfo($appkey, $username, $password)
1324    {
1325        return $this->getUserInfo($username, $password);
1326    }
[2566]1327
[3730]1328    /* Metaweblog methods
1329    ------------------------------------------------------- */
1330    public function mw_newPost($blogid, $username, $password, $content, $publish)
1331    {
1332        return $this->newPost($blogid, $username, $password, '', $content, $publish);
1333    }
[2566]1334
[3730]1335    public function mw_editPost($postid, $username, $password, $content, $publish)
1336    {
1337        return $this->editPost($postid, $username, $password, '', $content, $publish);
1338    }
[2566]1339
[3730]1340    public function mw_getPost($postid, $username, $password)
1341    {
1342        return $this->getPost($postid, $username, $password, 'mw');
1343    }
[2566]1344
[3730]1345    public function mw_getRecentPosts($blogid, $username, $password, $numberOfPosts)
1346    {
1347        return $this->getRecentPosts($blogid, $username, $password, $numberOfPosts, 'mw');
1348    }
[2566]1349
[3730]1350    public function mw_getCategories($blogid, $username, $password)
1351    {
1352        return $this->getCategories($blogid, $username, $password);
1353    }
[2566]1354
[3730]1355    public function mw_newMediaObject($blogid, $username, $password, $file)
1356    {
1357        return $this->newMediaObject($blogid, $username, $password, $file);
1358    }
[2566]1359
[3730]1360    /* MovableType methods
1361    --------------------------------------------------- */
1362    public function mt_getRecentPostTitles($blogid, $username, $password, $numberOfPosts)
1363    {
1364        return $this->getRecentPosts($blogid, $username, $password, $numberOfPosts, 'mt');
1365    }
[2566]1366
[3730]1367    public function mt_getCategoryList($blogid, $username, $password)
1368    {
1369        return $this->getCategories($blogid, $username, $password);
1370    }
[2566]1371
[3730]1372    public function mt_getPostCategories($postid, $username, $password)
1373    {
1374        return $this->getPostCategories($postid, $username, $password);
1375    }
[2566]1376
[3730]1377    public function mt_setPostCategories($postid, $username, $password, $categories)
1378    {
1379        return $this->setPostCategories($postid, $username, $password, $categories);
1380    }
[2566]1381
[3730]1382    public function mt_publishPost($postid, $username, $password)
1383    {
1384        return $this->publishPost($postid, $username, $password);
1385    }
[2566]1386
[3730]1387    public function mt_supportedTextFilters()
1388    {
[3874]1389        return [];
[3730]1390    }
[2566]1391
[3730]1392    /* WordPress methods
1393    --------------------------------------------------- */
1394    public function wp_getUsersBlogs($username, $password)
1395    {
1396        return $this->getUserBlogs($username, $password);
1397    }
[2566]1398
[3730]1399    public function wp_getPage($blogid, $pageid, $username, $password)
1400    {
1401        $res = $this->getPages($blogid, $username, $password, null, $pageid);
[2566]1402
[3730]1403        if (empty($res)) {
1404            throw new Exception('Sorry, no such page', 404);
1405        }
[2566]1406
[3730]1407        return $res[0];
1408    }
[2566]1409
[3730]1410    public function wp_getPages($blogid, $username, $password, $num = 10)
1411    {
1412        return $this->getPages($blogid, $username, $password, $num);
1413    }
[2566]1414
[3730]1415    public function wp_newPage($blogid, $username, $password, $content, $publish)
1416    {
1417        return $this->newPage($blogid, $username, $password, $content, $publish);
1418    }
[2566]1419
[3730]1420    public function wp_deletePage($blogid, $username, $password, $pageid)
1421    {
1422        return $this->deletePage($pageid, $username, $password);
1423    }
[2566]1424
[3730]1425    public function wp_editPage($blogid, $pageid, $username, $password, $content, $publish)
1426    {
1427        return $this->editPage($pageid, $username, $password, $content, $publish);
1428    }
[2566]1429
[3730]1430    public function wp_getPageList($blogid, $username, $password)
1431    {
1432        $A   = $this->getPages($blogid, $username, $password);
[3874]1433        $res = [];
[3730]1434        foreach ($A as $v) {
[3874]1435            $res[] = [
[3730]1436                'page_id'          => $v['page_id'],
1437                'page_title'       => $v['title'],
1438                'page_parent_id'   => $v['wp_page_parent_id'],
1439                'dateCreated'      => $v['dateCreated'],
1440                'date_created_gmt' => $v['date_created_gmt']
[3874]1441            ];
[3730]1442        }
1443        return $res;
1444    }
[2566]1445
[3730]1446    public function wp_getAuthors($blogid, $username, $password)
1447    {
1448        return $this->getAuthors($username, $password);
1449    }
[2566]1450
[3730]1451    public function wp_getCategories($blogid, $username, $password)
1452    {
1453        return $this->getCategories($blogid, $username, $password);
1454    }
[2566]1455
[3730]1456    public function wp_getTags($blogid, $username, $password)
1457    {
1458        return $this->getTags($username, $password);
1459    }
[2566]1460
[3730]1461    public function wp_newCategory($blogid, $username, $password, $content)
1462    {
1463        return $this->newCategory($username, $password, $content);
1464    }
[2566]1465
[3730]1466    public function wp_deleteCategory($blogid, $username, $password, $categoryid)
1467    {
1468        return $this->deleteCategory($username, $password, $categoryid);
1469    }
[2566]1470
[3730]1471    public function wp_suggestCategories($blogid, $username, $password, $category, $max_results = 0)
1472    {
1473        return $this->searchCategories($username, $password, $category, $max_results);
1474    }
[2566]1475
[3730]1476    public function wp_uploadFile($blogid, $username, $password, $file)
1477    {
1478        return $this->newMediaObject($blogid, $username, $password, $file);
1479    }
[2566]1480
[3730]1481    public function wp_getPostStatusList($blogid, $username, $password)
1482    {
1483        return $this->getPostStatusList($blogid, $username, $password);
1484    }
[2566]1485
[3730]1486    public function wp_getPageStatusList($blogid, $username, $password)
1487    {
1488        return $this->getPostStatusList($blogid, $username, $password);
1489    }
[2566]1490
[3730]1491    public function wp_getPageTemplates($blogid, $username, $password)
1492    {
[3874]1493        return ['Default' => 'default'];
[3730]1494    }
[2566]1495
[3874]1496    public function wp_getOptions($blogid, $username, $password, $options = [])
[3730]1497    {
1498        $this->setUser($username, $password);
1499        $this->setBlog();
[2566]1500
[3730]1501        return $this->translateWpOptions($options);
1502    }
[2566]1503
[3730]1504    public function wp_setOptions($blogid, $username, $password, $options)
1505    {
1506        $this->setUser($username, $password);
1507        $this->setBlog();
[2566]1508
[3730]1509        if (!$this->core->auth->check('admin', $this->core->blog->id)) {
1510            throw new Exception('Not enough permissions to edit options.', 401);
1511        }
[2566]1512
[3730]1513        $opt = $this->translateWpOptions();
[2566]1514
[3874]1515        $done         = [];
[3730]1516        $blog_changes = false;
1517        $cur          = $this->core->con->openCursor($this->core->prefix . 'blog');
[2566]1518
[3730]1519        $this->core->blog->settings->addNamespace('system');
[2566]1520
[3730]1521        foreach ($options as $name => $value) {
1522            if (!isset($opt[$name]) || $opt[$name]['readonly']) {
1523                continue;
1524            }
[2566]1525
[3730]1526            switch ($name) {
1527                case 'blog_title':
1528                    $blog_changes   = true;
1529                    $cur->blog_name = $value;
1530                    $done[]         = $name;
1531                    break;
1532                case 'blog_tagline':
1533                    $blog_changes   = true;
1534                    $cur->blog_desc = $value;
1535                    $done[]         = $name;
1536                    break;
1537                case 'date_format':
1538                    $this->core->blog->settings->system->put('date_format', $value);
1539                    $done[] = $name;
1540                    break;
1541                case 'time_format':
1542                    $this->core->blog->settings->system->put('time_format', $value);
1543                    $done[] = $name;
1544                    break;
1545            }
1546        }
[2566]1547
[3730]1548        if ($blog_changes) {
1549            $this->core->updBlog($this->core->blog->id, $cur);
1550            $this->core->setBlog($this->core->blog->id);
1551        }
[2566]1552
[3730]1553        return $this->translateWpOptions($done);
1554    }
[2566]1555
[3730]1556    public function wp_getComment($blogid, $username, $password, $commentid)
1557    {
[3874]1558        $res = $this->getComments($username, $password, [], $commentid);
[2566]1559
[3730]1560        if (empty($res)) {
1561            throw new Exception('Sorry, no such comment', 404);
1562        }
[2566]1563
[3730]1564        return $res[0];
1565    }
[2566]1566
[3730]1567    public function wp_getCommentCount($blogid, $username, $password, $postid)
1568    {
1569        return $this->countComments($username, $password, $postid);
1570    }
[2566]1571
[3730]1572    public function wp_getComments($blogid, $username, $password, $struct)
1573    {
1574        return $this->getComments($username, $password, $struct);
1575    }
[2566]1576
[3730]1577    public function wp_deleteComment($blogid, $username, $password, $commentid)
1578    {
1579        return $this->delComment($username, $password, $commentid);
1580    }
[2566]1581
[3730]1582    public function wp_editComment($blogid, $username, $password, $commentid, $content)
1583    {
1584        return $this->updComment($username, $password, $commentid, $content);
1585    }
[2566]1586
[3730]1587    public function wp_newComment($blogid, $username, $password, $postid, $content)
1588    {
1589        return $this->addComment($username, $password, $postid, $content);
1590    }
[2566]1591
[3730]1592    public function wp_getCommentStatusList($blogid, $username, $password)
1593    {
1594        $this->setUser($username, $password);
1595        $this->setBlog();
[2566]1596
[3874]1597        return [
[3730]1598            'hold'    => 'Unapproved',
1599            'approve' => 'Approved',
1600            'spam'    => 'Spam'
[3874]1601        ];
[3730]1602    }
[2566]1603
[3730]1604    /* Pingback support
1605    --------------------------------------------------- */
1606    public function pingback_ping($from_url, $to_url)
1607    {
1608        dcTrackback::checkURLs($from_url, $to_url);
[2566]1609
[3874]1610        $args = ['type' => 'pingback', 'from_url' => $from_url, 'to_url' => $to_url];
[1674]1611
[3730]1612        # Time to get things done...
1613        $this->setBlog(true);
[1687]1614
[3730]1615        # --BEHAVIOR-- publicBeforeReceiveTrackback
1616        $this->core->callBehavior('publicBeforeReceiveTrackback', $this->core, $args);
[2566]1617
[3730]1618        $tb = new dcTrackback($this->core);
1619        return $tb->receivePingback($from_url, $to_url);
1620    }
[0]1621}
Note: See TracBrowser for help on using the repository browser.

Sites map