Dotclear

source: inc/core/class.dc.xmlrpc.php @ 3170:7f517983e0d4

Revision 3170:7f517983e0d4, 44.7 KB checked in by franck <carnet.franck.paul@…>, 9 years ago (diff)

Do not decode twice base64 encoded data of uploaded media (XML-RPC), fixes #2144

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

Sites map