Source for file metaweblog_api.php

Documentation is available at metaweblog_api.php

  1. <?php
  2. /**
  3. * Meta Weblog API
  4. *
  5. * @todo Document
  6. * @todo Reformat
  7. *
  8. * @package de.linkm.newsticker
  9. * @author The Midgard Project, http://www.midgard-project.org
  10. * @version $Id: metaweblog_api.php,v 1.7 2005/04/15 18:28:40 bergius Exp $
  11. * @copyright The Midgard Project, http://www.midgard-project.org
  12. * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
  13. */
  14.  
  15. /*
  16. Server functions for implementing MetaWebLog API and Blogger API for newsticker
  17. http://www.xmlrpc.com/metaWeblogApi
  18. http://xmlrpc.free-conversant.com/docs/bloggerAPI
  19.  
  20. Henri Bergius <henri.bergius@iki.fi>
  21.  
  22. TODO:
  23. Category support if available as selection list in schema
  24. Rest of Blogger API
  25. */
  26.  
  27. // Include PEAR XML-RPC library
  28. error_reporting(E_ERROR);
  29. include_once("XML/RPC/Server.php");
  30. error_reporting(E_ALL);
  31.  
  32. // Check if the library was found
  33. if (class_exists("XML_RPC_Server")) {
  34.  
  35. function de_linkm_newsticker_metaweblog_helper_getCategoryField() {
  36.  
  37. // Parse schema
  38. $schema = $GLOBALS["de_linkm_newsticker_layouts"]["default"];
  39.  
  40. if (isset($schema["fields"]["categories"]) && $schema["fields"]["categories"]["datatype"] == "multiselect") {
  41. // Multiple select
  42. $schema["fields"]["categories"]["name"] = "categories";
  43. return $schema["fields"]["categories"];
  44.  
  45. } elseif (isset($schema["fields"]["category"]) && ((isset($schema["fields"]["category"]["widget"]) && $schema["fields"]["category"]["widget"] == "select") || $schema["fields"]["category"]["datatype"] == "multiselect")) {
  46. // Select or multiple select
  47. $schema["fields"]["category"]["name"] = "category";
  48. return $schema["fields"]["category"];
  49.  
  50. } else {
  51. return false;
  52. }
  53.  
  54. }
  55.  
  56. function de_linkm_newsticker_metaweblog_helper_getCategories() {
  57.  
  58. $categories = array();
  59.  
  60. $field = de_linkm_newsticker_metaweblog_helper_getCategoryField();
  61.  
  62. // Multiple select categories
  63. if ($field && isset($field["multiselect_selection_list"])) {
  64. foreach ($field["multiselect_selection_list"] as $key => $description) {
  65. $categories[$key] = $description;
  66. }
  67. }
  68.  
  69. // Select categories
  70. if ($field && isset($field["widget_select_choices"])) {
  71. foreach ($field["widget_select_choices"] as $key => $description) {
  72. $categories[$key] = $description;
  73. }
  74. }
  75.  
  76. if (count($categories) == 0) {
  77. $topic = mgd_get_topic($GLOBALS["de_linkm_newsticker_topic"]);
  78. $categories[$topic->name] = $topic->extra;
  79. }
  80.  
  81. return $categories;
  82.  
  83. }
  84.  
  85. function de_linkm_newsticker_metaweblog_helper_categoriesToStorage($categories,$storage) {
  86. $categories_field = de_linkm_newsticker_metaweblog_helper_getCategoryField();
  87. if ($categories_field && is_array($categories)) {
  88.  
  89. // Check for unknown categories
  90. foreach($categories as $key => $category) {
  91. if (isset($categories_field["multiselect_selection_list"])) {
  92. if (!array_key_exists($category,$categories_field["multiselect_selection_list"])) {
  93. unset($categories[$key]);
  94. }
  95. } else {
  96. if (!array_key_exists($category,$categories_field["widget_select_choices"])) {
  97. unset($categories[$key]);
  98. }
  99. }
  100. }
  101.  
  102. // Store the categories
  103. if (isset($categories_field["location"]) && $categories_field["location"] == "parameter") {
  104.  
  105. if ($categories_field["datatype"] == "multiselect") {
  106. $storage->parameter("midcom.helper.datamanager","data_".$categories_field["name"],implode(",",$categories));
  107. } else {
  108. // Note: this always stores the first one
  109. $storage->parameter("midcom.helper.datamanager","data_".$categories_field["name"],$categories[0]);
  110. }
  111. }
  112. }
  113. }
  114.  
  115. function de_linkm_newsticker_metaweblog_helper_categoriesFromStorage($storage) {
  116. $categories_field = de_linkm_newsticker_metaweblog_helper_getCategoryField();
  117. $categories = null;
  118.  
  119. if ($categories_field) {
  120.  
  121. // Load the categories
  122. if (isset($categories_field["location"]) && $categories_field["location"] == "parameter") {
  123. if ($categories_field["datatype"] == "multiselect") {
  124. if ($storage->parameter("midcom.helper.datamanager","data_".$categories_field["name"])) {
  125. $categories = explode(",",$storage->parameter("midcom.helper.datamanager","data_".$categories_field["name"]));
  126. }
  127. } else {
  128. if ($storage->parameter("midcom.helper.datamanager","data_category")) {
  129. $categories[0] = $storage->parameter("midcom.helper.datamanager","data_category");
  130. }
  131. }
  132. }
  133.  
  134. if (is_array($categories)) {
  135. // Check for unknown categories
  136. foreach($categories as $key => $category) {
  137. if (isset($categories_field["multiselect_selection_list"])) {
  138. if (!array_key_exists($category,$categories_field["multiselect_selection_list"])) {
  139. unset($categories[$key]);
  140. }
  141. } else {
  142. if (!array_key_exists($category,$categories_field["widget_select_choices"])) {
  143. unset($categories[$key]);
  144. }
  145. }
  146. }
  147. }
  148. }
  149.  
  150. return $categories;
  151.  
  152. }
  153.  
  154. function de_linkm_newsticker_metaweblog_createURL($local_path="",$skip_prefix = false) {
  155. $server_url = $GLOBALS["midcom"]->get_host_name();
  156. if ($skip_prefix) {
  157. $prefix = $GLOBALS["midgard"]->self;
  158. } else {
  159. $prefix = str_replace("rpc/metaweblog/","",$GLOBALS["midgard"]->uri);
  160. }
  161. return $server_url.$prefix.$local_path;
  162. }
  163.  
  164. // MetaWebLog API
  165. // metaWeblog.newPost
  166. function de_linkm_newsticker_metaweblog_newPost($params) {
  167. global $xmlrpcerruser;
  168. //error_log("metaWeblog.newPost called", 0);
  169. // Authenticate into Midgard
  170. $username = $params->getparam(1);
  171. $username = $username->scalarval();
  172. $password = $params->getparam(2);
  173. $password = $password->scalarval();
  174.  
  175. if ($username && $password) {
  176. mgd_auth_midgard($username, $password, 0);
  177. $midgard = mgd_get_midgard();
  178.  
  179. if ($midgard->user) {
  180.  
  181. // Instantiate the article
  182. $article = mgd_get_article();
  183. $article->author = $midgard->user;
  184. $article->topic = $GLOBALS["de_linkm_newsticker_topic"];
  185.  
  186. $struct = $params->getparam(3);
  187. // Populate article with data from the request
  188. if ($struct->kindOf() == "struct") {
  189.  
  190. $categories = null;
  191.  
  192. while (list($key,$value) = $struct->structeach()) {
  193.  
  194. if ($key == "title") {
  195. $article->title = $value->scalarval();
  196. }
  197.  
  198. if ($key == "description") {
  199. $article->content = $value->scalarval();
  200. }
  201.  
  202. if ($key == "mt_excerpt") {
  203. $article->abstract = $value->scalarval();
  204. }
  205.  
  206. if ($key == "categories") {
  207. $categories = XML_RPC_decode($value);
  208. }
  209.  
  210. }
  211. }
  212.  
  213. // Check that the document has some content
  214. if ($article->title) {
  215.  
  216. $stat = false;
  217. $tries = 0;
  218. $maxtries = 99;
  219. while(!$stat && $tries < $maxtries) {
  220. $article->name = midcom_generate_urlname_from_string($article->title);
  221. if ($tries > 0) {
  222. // Append an integer if articles with same name exist
  223. $article->name .= sprintf("-%03d", $tries);
  224. }
  225. $stat = $article->create();
  226. $tries++;
  227. }
  228. // Invalidate the cache
  229. $GLOBALS['midcom']->cache->invalidate_all();
  230. // Update the Index
  231. // We create a datamanager for this.
  232. $config = $GLOBALS['midcom']->get_custom_context_data('config');
  233. $datamanager = new midcom_helper_datamanager($config->get('schemadb'));
  234. if (! $datamanager)
  235. {
  236. debug_add('Warning, failed to create a datamanager instance with this schemapath:' . $this->_config->get('schemadb'),
  237. MIDCOM_LOG_WARN);
  238. }
  239. else
  240. {
  241. if (! $datamanager->init($article))
  242. {
  243. debug_add("Warning, failed to initialize datamanager for Article {$article->id}. See Debug Log for details.", MIDCOM_LOG_WARN);
  244. debug_print_r('Article dump:', $article);
  245. }
  246. else
  247. {
  248. $indexer =& $GLOBALS['midcom']->get_service('indexer');
  249. $indexer->index($datamanager);
  250. }
  251. }
  252.  
  253. // Return status information
  254. if ($stat) {
  255. $article = mgd_get_article($stat);
  256. if ($categories) {
  257. de_linkm_newsticker_metaweblog_helper_categoriesToStorage($categories,$article);
  258. }
  259. return new XML_RPC_Response(new XML_RPC_Value($article->guid(), "string"));
  260. } else {
  261. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  262. }
  263.  
  264. } else {
  265. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),"Missing title");
  266. }
  267. }
  268. }
  269.  
  270. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  271.  
  272. }
  273.  
  274. // metaWebLog.editPost
  275. function de_linkm_newsticker_metaweblog_editPost($params) {
  276. //error_log("metaWeblog.editPost called", 0);
  277. global $xmlrpcerruser;
  278.  
  279. // Authenticate into Midgard
  280. $username = $params->getparam(1);
  281. $username = $username->scalarval();
  282. $password = $params->getparam(2);
  283. $password = $password->scalarval();
  284.  
  285. if ($username && $password) {
  286. mgd_auth_midgard($username, $password, 0);
  287. $midgard = mgd_get_midgard();
  288.  
  289. if ($midgard->user) {
  290.  
  291. // Instantiate the article
  292. $article_id = $params->getparam(0);
  293. $article_id = $article_id->scalarval();
  294.  
  295. $article = mgd_get_object_by_guid($article_id);
  296. if ($article && get_class($article) == "MidgardArticle" && $article->topic == $GLOBALS["de_linkm_newsticker_topic"]) {
  297.  
  298.  
  299. $struct = $params->getparam(3);
  300. // Populate article with data from the request
  301. if ($struct->kindOf() == "struct") {
  302.  
  303. while (list($key,$value) = $struct->structeach()) {
  304.  
  305. if ($key == "title") {
  306. $article->title = $value->scalarval();
  307. }
  308.  
  309. if ($key == "description") {
  310. $article->content = $value->scalarval();
  311. }
  312.  
  313. if ($key == "mt_excerpt") {
  314. $article->abstract = $value->scalarval();
  315. }
  316.  
  317. if ($key == "categories") {
  318. $categories = XML_RPC_decode($value);
  319. de_linkm_newsticker_metaweblog_helper_categoriesToStorage($categories,$article);
  320. }
  321.  
  322. }
  323.  
  324. // Save the article
  325. $stat = $article->update();
  326.  
  327. // Invalidate the cache
  328. $GLOBALS['midcom']->cache->invalidate_all();
  329.  
  330. // Update the Index
  331. // We create a datamanager for this.
  332. $config = $GLOBALS['midcom']->get_custom_context_data('config');
  333. $datamanager = new midcom_helper_datamanager($config->get('schemadb'));
  334. if (! $datamanager)
  335. {
  336. debug_add('Warning, failed to create a datamanager instance with this schemapath:' . $this->_config->get('schemadb'),
  337. MIDCOM_LOG_WARN);
  338. }
  339. else
  340. {
  341. if (! $datamanager->init($article))
  342. {
  343. debug_add("Warning, failed to initialize datamanager for Article {$article->id}. See Debug Log for details.", MIDCOM_LOG_WARN);
  344. debug_print_r('Article dump:', $article);
  345. }
  346. else
  347. {
  348. $indexer =& $GLOBALS['midcom']->get_service('indexer');
  349. $indexer->index($datamanager);
  350. }
  351. }
  352.  
  353. // Return status information
  354. if ($stat) {
  355. return new XML_RPC_Response(new XML_RPC_Value($article->id, "string"));
  356. //return new XML_RPC_Response(new XML_RPC_Value(1, "boolean"));
  357. } else {
  358. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  359. }
  360. }
  361. }
  362. }
  363. }
  364.  
  365. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  366.  
  367. }
  368.  
  369. // metaWebLog.getPost
  370. function de_linkm_newsticker_metaweblog_getPost($params) {
  371. //error_log("metaWeblog.getPost called", 0);
  372. global $xmlrpcerruser;
  373.  
  374. // Authenticate into Midgard
  375. $username = $params->getparam(1);
  376. $username = $username->scalarval();
  377. $password = $params->getparam(2);
  378. $password = $password->scalarval();
  379.  
  380. if ($username && $password) {
  381. mgd_auth_midgard($username, $password, 0);
  382. $midgard = mgd_get_midgard();
  383.  
  384. if ($midgard->user) {
  385.  
  386. // Instantiate the article
  387. $article_id = $params->getparam(0);
  388. $article_id = $article_id->scalarval();
  389.  
  390. $article = mgd_get_object_by_guid($article_id);
  391.  
  392. if ($article && get_class($article) == "MidgardArticle" && $article->topic == $GLOBALS["de_linkm_newsticker_topic"]) {
  393. $article_created = date("Ymd", $article->created)."T".date("H:i:s", $article->created);
  394. $response_array = array();
  395. $response_array["postid"] = new XML_RPC_Value($article->guid(),"string");
  396. $response_array["title"] = new XML_RPC_Value($article->title,"string");
  397. if ($article->content) {
  398. $response_array["description"] = new XML_RPC_Value($article->content,"string");
  399. }
  400. if ($article->abstract) {
  401. $response_array["mt_excerpt"] = new XML_RPC_Value($articles->abstract,"string");
  402. }
  403.  
  404. $categories = de_linkm_newsticker_metaweblog_helper_categoriesFromStorage($article);
  405. if ($categories) {
  406. $response_array["categories"] = XML_RPC_encode($categories);
  407. }
  408.  
  409. $response_array["permaLink"] = new XML_RPC_Value(de_linkm_newsticker_metaweblog_createURL($article->name.".html"),"string");
  410. $response_array["link"] = new XML_RPC_Value(de_linkm_newsticker_metaweblog_createURL($article->name.".html"),"string");
  411. $response_array["dateCreated"] = new XML_RPC_Value($article_created,"dateTime.iso8601");
  412. return new XML_RPC_Response(new XML_RPC_Value($response_array,"struct"));
  413. }
  414. }
  415. }
  416.  
  417. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  418.  
  419. }
  420.  
  421. // metaWeblog.getRecentPosts
  422. function de_linkm_newsticker_metaweblog_getRecentPosts($params) {
  423. //error_log("metaWeblog.getRecentPosts called", 0);
  424. global $xmlrpcerruser;
  425.  
  426. // Authenticate into Midgard
  427. $username = $params->getparam(1);
  428. if ($username) {
  429. $username = $username->scalarval();
  430. }
  431. $password = $params->getparam(2);
  432. if ($password) {
  433. $password = $password->scalarval();
  434. }
  435.  
  436. if ($username && $password) {
  437. mgd_auth_midgard($username, $password, 0);
  438. $midgard = mgd_get_midgard();
  439.  
  440. if ($midgard->user) {
  441.  
  442. // Instantiate the article
  443. $article_count = $params->getparam(3);
  444. $article_count = $article_count->scalarval();
  445.  
  446. $response = array();
  447.  
  448. $articles = mgd_list_topic_articles($GLOBALS["de_linkm_newsticker_topic"],"reverse created");
  449. if ($articles) {
  450. while ($articles->fetch() && $article_count > 0) {
  451. $article = mgd_get_article($articles->id);
  452.  
  453. $article_created = date("Ymd", $article->created)."T".date("H:i:s", $article->created);
  454.  
  455. $response_array = array();
  456. $response_array["postid"] = new XML_RPC_Value($article->guid(),"string");
  457. $response_array["title"] = new XML_RPC_Value($article->title,"string");
  458. $response_array["permaLink"] = new XML_RPC_Value(de_linkm_newsticker_metaweblog_createURL($article->name.".html"),"string");
  459. $response_array["link"] = new XML_RPC_Value(de_linkm_newsticker_metaweblog_createURL($article->name.".html"),"string");
  460. if ($article->content) {
  461. $response_array["description"] = new XML_RPC_Value($articles->content,"string");
  462. }
  463. if ($article->abstract) {
  464. $response_array["mt_excerpt"] = new XML_RPC_Value($articles->abstract,"string");
  465. }
  466.  
  467. $categories = de_linkm_newsticker_metaweblog_helper_categoriesFromStorage($article);
  468. if ($categories) {
  469. $response_array["categories"] = XML_RPC_encode($categories);
  470. }
  471.  
  472. $response_array["dateCreated"] = new XML_RPC_Value($article_created,"dateTime.iso8601");
  473.  
  474. $response[] = new XML_RPC_Value($response_array,"struct");
  475.  
  476. $article_count--;
  477. }
  478. }
  479.  
  480. return new XML_RPC_Response(new XML_RPC_Value($response,"array"));
  481. }
  482. }
  483.  
  484. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  485.  
  486. }
  487.  
  488. // metaWeblog.getCategories
  489. function de_linkm_newsticker_metaweblog_getCategories($params) {
  490. //error_log("metaWeblog.getCategories called", 0);
  491. global $xmlrpcerruser;
  492.  
  493. // Authenticate into Midgard
  494. $username = $params->getparam(1);
  495. $username = $username->scalarval();
  496. $password = $params->getparam(2);
  497. $password = $password->scalarval();
  498.  
  499. if ($username && $password) {
  500. mgd_auth_midgard($username, $password, 0);
  501. $midgard = mgd_get_midgard();
  502.  
  503. if ($midgard->user) {
  504.  
  505. $categories = de_linkm_newsticker_metaweblog_helper_getCategories("xml-rpc");
  506. $category_structs = array();
  507. foreach ($categories as $key => $description) {
  508. $category_structs[$key] = new XML_RPC_Value(array(
  509. "description" => new XML_RPC_Value($description,"string"),
  510. "htmlUrl" => new XML_RPC_Value(de_linkm_newsticker_metaweblog_createURL(),"string"),
  511. "rssUrl" => new XML_RPC_Value(de_linkm_newsticker_metaweblog_createURL("rss.xml"),"string")
  512. ),"struct");
  513. }
  514. // Return cats
  515. return new XML_RPC_Response(
  516. new XML_RPC_Value($category_structs,"struct")
  517. );
  518. }
  519. }
  520. }
  521.  
  522. // metaWeblog.newMediaObject
  523. function de_linkm_newsticker_metaweblog_newMediaObject($params) {
  524. global $xmlrpcerruser;
  525.  
  526. // Authenticate into Midgard
  527. $username = $params->getparam(1);
  528. $username = $username->scalarval();
  529. $password = $params->getparam(2);
  530. $password = $password->scalarval();
  531.  
  532. if ($username && $password) {
  533. mgd_auth_midgard($username, $password, 0);
  534. $midgard = mgd_get_midgard();
  535.  
  536. if ($midgard->user) {
  537.  
  538. $struct = $params->getparam(3);
  539. // Populate with data from the request
  540. if ($struct->kindOf() == "struct") {
  541.  
  542. while (list($key,$value) = $struct->structeach()) {
  543.  
  544. if ($key == "name") {
  545. $attachment_name = basename($value->scalarval()) ;
  546. }
  547.  
  548. if ($key == "type") {
  549. $attachment_type = $value->scalarval();
  550. }
  551.  
  552. if ($key == "bits") {
  553. // File contents base64 encoded but XML-RPC library handles that
  554. $attachment_content = $value->scalarval();
  555. }
  556.  
  557. }
  558. }
  559.  
  560. // Check that the attachment is correct
  561. if ($attachment_name && $attachment_type && $attachment_content) {
  562.  
  563. $attachment_id = false;
  564. $topic = mgd_get_topic($GLOBALS["de_linkm_newsticker_topic"]);
  565. $attachments = $topic->listattachments();
  566. if ($attachments) {
  567. while ($attachments->fetch()) {
  568. if ($attachments->name == $attachment_name) {
  569. $attachment_id = $attachments->id;
  570. }
  571. }
  572. }
  573.  
  574. if (!$attachment_id) {
  575. $attachment_id = $topic->createattachment($attachment_name,$attachment_name,$attachment_type);
  576. }
  577.  
  578. if ($attachment_id) {
  579.  
  580. // Write the contents to the attachment
  581. $attachment_handle = mgd_open_attachment($attachment_id,"w");
  582. fputs($attachment_handle, $attachment_content);
  583. fclose($attachment_handle);
  584.  
  585. $attachment = mgd_get_attachment($attachment_id);
  586. $attachment_url = de_linkm_newsticker_metaweblog_createURL("midcom-serveattachmentguid-".$attachment->guid()."/".$attachment->name,true);
  587.  
  588. return new XML_RPC_Response(new XML_RPC_Value(array(
  589. "url" => new XML_RPC_Value($attachment_url,"string"),
  590. "guid" => new XML_RPC_Value($attachment->guid(), "string"),
  591. ), "struct"));
  592. } else {
  593. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  594. }
  595.  
  596. } else {
  597. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),"Missing title");
  598. }
  599. }
  600. }
  601.  
  602. return new XML_RPC_Response(0,$xmlrpcerruser+mgd_errno(),mgd_errstr());
  603.  
  604. }
  605.  
  606. // Blogger API
  607. // blogger.deletePost
  608. function de_linkm_newsticker_blogger_deletePost($params) {
  609. global $xmlrpcerruser;
  610.  
  611. // Authenticate into Midgard
  612. $username = $params->getparam(2);
  613. $username = $username->scalarval();
  614. $password = $params->getparam(3);
  615. $password = $password->scalarval();
  616.  
  617. if ($username && $password) {
  618. mgd_auth_midgard($username, $password, 0);
  619. $midgard = mgd_get_midgard();
  620.  
  621. if ($midgard->user) {
  622.  
  623. // Instantiate the article
  624. $article_id = $params->getparam(1);
  625. $article_id = $article_id->scalarval();
  626.  
  627. $article = mgd_get_object_by_guid($article_id);
  628.  
  629. if ($article && get_class($article