PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/web/nvweb_xmlrpc.php

https://bitbucket.org/navigatecms/navigatecms
PHP | 475 lines | 347 code | 75 blank | 53 comment | 35 complexity | aa5393695b0d396717774429d2483954 MD5 | raw file
Possible License(s): GPL-2.0, MIT, LGPL-2.1, BSD-3-Clause, AGPL-3.0, Apache-2.0
  1. <?php
  2. /* resources
  3. http://xmlrpc.scripting.com/metaWeblogApi.html
  4. https://codex.wordpress.org/XML-RPC_MetaWeblog_API
  5. http://blogs.technet.com/b/larsnakkerud/metablog.ashx
  6. */
  7. function nvweb_xmlrpc()
  8. {
  9. /* Functions defining the behaviour of the server */
  10. nvweb_webget_load('menu');
  11. nvweb_webget_load('content');
  12. function metaWeblog_getUsersBlogs($args)
  13. {
  14. global $DB;
  15. $out = array();
  16. list($appkey, $username, $password) = $args;
  17. $user = new user();
  18. $error = !$user->authenticate($username, $password);
  19. if(!empty($error) || $user->blocked == '1')
  20. {
  21. $out = new IXR_Error(401, "User not allowed.");
  22. }
  23. else
  24. {
  25. $websites_ids = $user->websites;
  26. if(empty($websites_ids))
  27. {
  28. // get all websites
  29. $DB->query('SELECT id FROM nv_websites WHERE permission = 0'); // only public websites
  30. $websites_ids = $DB->result();
  31. }
  32. if(is_array($websites_ids))
  33. {
  34. foreach($websites_ids as $wid)
  35. {
  36. $website = new website();
  37. $website->load($wid);
  38. $out[] = array(
  39. 'blogid' => $website->id, // website id
  40. 'url' => $website->absolute_path(true).$website->homepage(), // homepage
  41. 'blogName' => $website->name, // website name
  42. 'isAdmin' => false, // is admin, unused
  43. 'xmlrpc' => $website->absolute_path(true).'/xmlrpc' // URL endpoint to use for XML-RPC requests
  44. );
  45. }
  46. }
  47. }
  48. return $out;
  49. }
  50. function metaWeblog_getRecentPosts($args)
  51. {
  52. global $DB;
  53. global $session;
  54. $out = array();
  55. list($website_id, $username, $password, $number_of_posts) = $args;
  56. if(empty($number_of_posts))
  57. $number_of_posts = 50;
  58. // check auth
  59. if(metaWeblog_userAllowed($username, $password, $website_id))
  60. {
  61. $DB->query('
  62. SELECT id
  63. FROM nv_items
  64. WHERE website = '.$website_id.'
  65. AND permission < 2
  66. ORDER BY date_modified DESC
  67. LIMIT '.$number_of_posts.'
  68. ');
  69. $posts = $DB->result();
  70. foreach($posts as $post)
  71. {
  72. $item = new item();
  73. $item->load($post->id);
  74. if($item->embedding == 1)
  75. $link = nvweb_source_url('structure', $item->category, $session['lang']);
  76. else
  77. $link = $item->link($session['lang']);
  78. $category = new structure();
  79. $category->load($item->category);
  80. $content = $item->dictionary[$session['lang']]['section-main'];
  81. $content = nvweb_template_fix_download_paths($content);
  82. if(empty($item->date_to_display))
  83. $item->date_to_display = $item->date_created;
  84. $out[] = array(
  85. "postid" => $item->id,
  86. "userid" => $item->author,
  87. "dateCreated" => new IXR_Date($item->date_to_display), // iso8601
  88. "category" => $item->category,
  89. "title" => $item->dictionary[$session['lang']]['title'],
  90. "description" => $content,
  91. "url" => $link,
  92. "permalink" => $link,
  93. "mt_keywords" => $item->dictionary[$session['lang']]['tags']
  94. );
  95. }
  96. }
  97. else
  98. {
  99. $out = new IXR_Error(401, "User not allowed.");
  100. }
  101. return $out;
  102. }
  103. function metaWeblog_getCategories($args)
  104. {
  105. global $DB;
  106. global $session;
  107. $out = array();
  108. list($website_id, $username, $password) = $args;
  109. // check auth
  110. if(metaWeblog_userAllowed($username, $password, $website_id))
  111. {
  112. // get all public categories
  113. $DB->query('
  114. SELECT id
  115. FROM nv_structure
  116. WHERE website = '.protect($website_id).'
  117. AND permission < 2
  118. ORDER BY parent ASC, position ASC
  119. ');
  120. $categories = $DB->result();
  121. $website = new website();
  122. $website->load($website_id);
  123. foreach($categories as $category)
  124. {
  125. $cat = new structure();
  126. $cat->load($category->id);
  127. $url = '';
  128. if($cat->paths[$session['lang']])
  129. $url = $website->absolute_path(true).$cat->paths[$session['lang']];
  130. $out[] = array(
  131. "categoryId" => $cat->id,
  132. "parentId" => $cat->parent,
  133. "categoryName" => $cat->dictionary[$session['lang']]['title'],
  134. "categoryDescription" => $cat->template,
  135. "htmlUrl" => $url,
  136. "rssUrl" => "",
  137. "title" => $cat->dictionary[$session['lang']]['title'],
  138. "description" => $cat->template
  139. );
  140. }
  141. }
  142. else
  143. {
  144. $out = new IXR_Error(401, "User not allowed.");
  145. }
  146. return $out;
  147. }
  148. // Makes a new post to a designated weblog using the MetaWeblog API. Returns postid as a string
  149. function metaWeblog_newPost($args)
  150. {
  151. global $DB;
  152. global $session;
  153. $out = array();
  154. list($website_id, $username, $password, $post, $publish) = $args;
  155. // check auth
  156. if(metaWeblog_userAllowed($username, $password, $website_id))
  157. {
  158. $category_name = $post['categories'];
  159. $category = "";
  160. // category name is text, we have to find the category ID
  161. if(is_array($category_name))
  162. {
  163. $category_name = array_shift($category_name);
  164. $DB->query('
  165. SELECT s.id
  166. FROM nv_structure s
  167. WHERE s.website = '.intval($website_id).'
  168. AND s.id IN (
  169. SELECT w.node_id
  170. FROM nv_webdictionary w
  171. WHERE w.website = '.intval($website_id).'
  172. AND w.node_type = "structure"
  173. AND w.subtype = "title"
  174. AND w.text LIKE '.protect($category_name).'
  175. )
  176. ');
  177. $category = $DB->result('id');
  178. $category = $category[0];
  179. if(!isset($post['post_type']) || empty($post['post_type']))
  180. $post['post_type'] = 'post';
  181. }
  182. $template = 'content';
  183. $association = 'free';
  184. $embedded = '1';
  185. if($post['post_type'] == 'post')
  186. {
  187. $template = 'blog_entry';
  188. $association = 'category';
  189. $embedded = '0';
  190. }
  191. if(empty($post['dateCreated']))
  192. $post['dateCreated'] = date("c", time());
  193. if(!isset($post['mt_text_more']))
  194. $post['mt_text_more'] = "";
  195. $item = new item();
  196. $item->association = $association;
  197. $item->template = $template;
  198. $item->category = $category;
  199. $item->embedding = $embedded;
  200. $item->permission = ($publish? '0' : '1');
  201. $item->dictionary = array($session['lang'] => array());
  202. $item->paths = array($session['lang'] => array());
  203. $item->date_to_display = strtotime($post['dateCreated']);
  204. $item->dictionary[$session['lang']]['title'] = html_entity_decode($post['title']);
  205. $item->dictionary[$session['lang']]['section-main'] = $post['description'] . $post['mt_text_more'];
  206. $item->dictionary[$session['lang']]['tags'] = $post['mt_keywords'];
  207. $item->comments_enabled_to = ($post['mt_allow_comments']=='1'? 2 : 0); // everybody or nobody
  208. $item->save();
  209. $out = $item->id;
  210. }
  211. else
  212. {
  213. $out = new IXR_Error(401, "User not allowed.");
  214. }
  215. return $out;
  216. }
  217. // Updates and existing post to a designated weblog using the MetaWeblog API. Returns true if completed.
  218. function metaWeblog_editPost($args)
  219. {
  220. global $DB;
  221. global $session;
  222. $out = array();
  223. list($post_id, $username, $password, $post, $publish) = $args;
  224. // check auth
  225. if(metaWeblog_userAllowed($username, $password))
  226. {
  227. if(!isset($post['mt_text_more']))
  228. $post['mt_text_more'] = "";
  229. $item = new item();
  230. $item->load($post_id);
  231. $item->dictionary[$session['lang']]['title'] = $post['title'];
  232. $item->dictionary[$session['lang']]['section-main'] = $post['description'] . $post['mt_text_more'];
  233. if(isset($post['mt_keywords']))
  234. $item->dictionary[$session['lang']]['tags'] = $post['mt_keywords'];
  235. if(!is_null($publish))
  236. $item->permission = ($publish? '0' : '1');
  237. $out = $item->save();
  238. }
  239. else
  240. {
  241. $out = new IXR_Error(401, "User not allowed.");
  242. }
  243. return $out;
  244. }
  245. // Retrieves an existing post using the MetaWeblog API. Returns the MetaWeblog struct.
  246. function metaWeblog_getPost($args)
  247. {
  248. global $DB;
  249. global $session;
  250. $out = array();
  251. list($post_id, $username, $password) = $args;
  252. $item = new item();
  253. $item->load(intval($post_id));
  254. $website_id = $item->website;
  255. $website = new website();
  256. $website->load($website_id);
  257. // check auth
  258. if(metaWeblog_userAllowed($username, $password, $website_id))
  259. {
  260. if($item->embedding == 1)
  261. $link = nvweb_source_url('structure', $item->category, $session['lang']);
  262. else
  263. $link = $item->link($session['lang']);
  264. $category = new structure();
  265. $category->load($item->category);
  266. $content = $item->dictionary[$session['lang']]['section-main'];
  267. $content = nvweb_template_fix_download_paths($content);
  268. if(empty($item->date_to_display))
  269. $item->date_to_display = $item->date_created;
  270. $out = array(
  271. "postid" => $item->id,
  272. "userid" => $item->author,
  273. "dateCreated" => new IXR_Date($item->date_to_display), // iso8601
  274. "category" => $item->category,
  275. "title" => $item->dictionary[$session['lang']]['title'],
  276. "description" => $content,
  277. "url" => $link,
  278. "permalink" => $link,
  279. "mt_keywords" => $item->dictionary[$session['lang']]['tags']
  280. );
  281. }
  282. else
  283. {
  284. $out = new IXR_Error(401, "User not allowed.");
  285. }
  286. return $out;
  287. }
  288. // Deletes a post.
  289. /* NOT IMPLEMENTED
  290. function metaWeblog_deletePost($args)
  291. {
  292. global $DB;
  293. global $session;
  294. $out = array();
  295. list($post_id, $username, $password) = $args;
  296. // check auth
  297. if(metaWeblog_userAllowed($username, $password, $website_id))
  298. {
  299. $out = true;
  300. }
  301. else
  302. {
  303. $out = new IXR_Error(401, "User not allowed.");
  304. }
  305. return $out;
  306. }
  307. */
  308. // add a new media object
  309. function metaWeblog_newMediaObject($args)
  310. {
  311. global $DB;
  312. global $session;
  313. $out = array();
  314. list($website_id, $username, $password, $file_struct) = $args;
  315. // check auth
  316. if(metaWeblog_userAllowed($username, $password, $website_id))
  317. {
  318. $file_name_tmp = uniqid('metaweblog-upload-');
  319. file_put_contents(NAVIGATE_PRIVATE.'/'.$website_id.'/files/'.$file_name_tmp, $file_struct['bits']);
  320. $file = file::register_upload($file_name_tmp, $file_struct['name'], 0, NULL, false);
  321. @unlink(AVIGATE_PRIVATE.'/'.$website_id.'/files/'.$file_name_tmp); // if everything goes fine, file is renamed, so cannot be deleted here
  322. $out = array(
  323. 'id' => $file->id,
  324. 'file' => $file->name,
  325. 'url' => file::file_url($file->id, 'inline'),
  326. 'type' => $file->mime
  327. );
  328. }
  329. else
  330. {
  331. $out = new IXR_Error(401, "User not allowed.");
  332. }
  333. return $out;
  334. }
  335. // helper functions
  336. function metaWeblog_userAllowed($username, $password, $website_id=NULL)
  337. {
  338. $user = new user();
  339. $allowed = false;
  340. $error = !($user->authenticate($username, $password));
  341. if(empty($error) && $user->blocked != '1')
  342. {
  343. $websites_ids = $user->websites;
  344. if(!empty($website_id) && !empty($websites_ids))
  345. $allowed = in_array($website_id, $websites_ids);
  346. else
  347. $allowed = true;
  348. }
  349. return $allowed;
  350. }
  351. // if we have a RSD request, don't run the XMLRPC server, just give an XML respnse
  352. // http://cyber.law.harvard.edu/blogs/gems/tech/rsd.html
  353. if(isset($_GET['rsd']))
  354. {
  355. global $website;
  356. header('Content-Type: text/xml; charset=UTF-8', true);
  357. $out = array();
  358. $out[] = '<?xml version="1.0" encoding="UTF-8"?>';
  359. $out[] = '<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">';
  360. $out[] = '<service>';
  361. $out[] = ' <engineName>Navigate CMS</engineName>';
  362. $out[] = ' <engineLink>http://www.navigatecms.com</engineLink>';
  363. $out[] = ' <homePageLink>'.$website->absolute_path().'</homePageLink>';
  364. $out[] = ' <apis>';
  365. $out[] = ' <api name="MetaWeblog" blogID="'.$website->id.'" preferred="true" apiLink="'.$website->absolute_path().'/xmlrpc" />';
  366. $out[] = ' <api name="Blogger" blogID="'.$website->id.'" preferred="false" apiLink="'.$website->absolute_path().'/xmlrpc" />';
  367. $out[] = ' </apis>';
  368. $out[] = '</service>';
  369. $out[] = '</rsd>';
  370. echo implode("\n", $out);
  371. }
  372. else
  373. {
  374. // debug
  375. // $request = file_get_contents('php://input');
  376. // file_put_contents(NAVIGATE_PATH.'/web/request.txt', $request);
  377. // Create the server and map the XML-RPC method names to the relevant functions
  378. $server = new IXR_Server(
  379. array(
  380. // metaWeblog endpoints
  381. 'metaWeblog.newPost' => 'metaWeblog_newPost',
  382. 'metaWeblog.editPost' => 'metaWeblog_editPost',
  383. 'metaWeblog.getPost' => 'metaWeblog_getPost',
  384. 'metaWeblog.deletePost' => 'metaWeblog_deletePost',
  385. 'metaWeblog.newMediaObject' => 'metaWeblog_newMediaObject',
  386. 'metaWeblog.getCategories' => 'metaWeblog_getCategories',
  387. 'metaWeblog.getRecentPosts' => 'metaWeblog_getRecentPosts',
  388. 'metaWeblog.getUsersBlogs' => 'metaWeblog_getUsersBlogs',
  389. 'blogger.getUsersBlogs' => 'metaWeblog_getUsersBlogs'
  390. // TODO: PingBack endpoints
  391. //'pingback.ping' => 'pingback_ping',
  392. //'pingback.extensions.getPingbacks' => 'pingback_extensions_getPingbacks'
  393. )
  394. );
  395. }
  396. }
  397. ?>