[ Index ]
 

Code source de b2evolution 2.1.0-beta

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/blogs/xmlsrv/ -> xmlrpc.php (source)

   1  <?php
   2  /**

   3   * XML-RPC APIs

   4   *

   5   * This file implements the following XML-RPC remote procedures, to be called by remote clients:

   6   * - the B2 API for b2evo (this is used by w.bloggar for example...)

   7   * - the BLOGGER API for b2evo, see {@link http://www.blogger.com/developers/api/1_docs/}

   8   * - Metaweblog API

   9   * - Movable Type API (partial)

  10   *

  11   * b2evolution - {@link http://b2evolution.net/}

  12   * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}

  13   * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/}

  14   *

  15   * @package xmlsrv

  16   *

  17   * @version $Id: xmlrpc.php,v 1.139 2007/06/27 02:23:32 fplanque Exp $

  18   *

  19   * @modified wendall911 at users dot sourceforge.net

  20   */
  21  
  22  /**

  23   * Initialize everything:

  24   */
  25  
  26  // Disable Cookies

  27  $_COOKIE = array();
  28  
  29  if( ! isset($HTTP_RAW_POST_DATA) )
  30  {
  31      $HTTP_RAW_POST_DATA = implode("\r\n", file('php://input'));
  32  }
  33  // Trim requests (used by XML-RPC library); fix for mozBlog and other cases where '<?xml' isn't on the very first line

  34  $HTTP_RAW_POST_DATA = trim( $HTTP_RAW_POST_DATA );
  35  
  36  
  37  /**

  38   * Set to TRUE to do HTML sanity checking as in the browser interface, set to

  39   * FALSE if you trust the editing tool to do this (more features than the

  40   * browser interface)

  41      * @todo fp> have a global setting with 3 options: check|nocheck|userdef => each then has his own setting to define if his tool does the checking or not.

  42      * fp> Also, there should be a permission to say if members of a given group can or cannot post insecure content. If they cannot, then they cannot disable the sanity check

  43      * fp> note: if allowed unsecure posting, disabling the sanity cjecker should also be allowed in the html backoffice

  44   */
  45  $xmlrpc_htmlchecking = true;
  46  require_once dirname(__FILE__).'/../conf/_config.php';
  47  require_once $inc_path.'_main.inc.php';
  48  load_funcs('_ext/xmlrpc/_xmlrpc.php');
  49  load_class('items/model/_itemlist.class.php');
  50  
  51  if( CANUSEXMLRPC !== TRUE )
  52  { // We cannot use XML-RPC: send a error response ( "1 Unknown method" ).
  53      //this should be structured as an xml response

  54      $errResponse = new xmlrpcresp( 0, 1, 'Cannot use XML-RPC. Probably the server is missing the XML extension. Error: '.CANUSEXMLRPC );
  55      die( $errResponse->serialize() );
  56  }
  57  
  58  
  59  // Handle "Really Simple Discovery":

  60  if ( isset( $_GET['rsd'] ) ) { // http://archipelago.phrasewise.com/rsd
  61  header('Content-type: text/xml; charset=' . $evo_charset, true);
  62  
  63  ?>
  64  <?php echo '<?xml version="1.0" encoding="'.$evo_charset.'"?'.'>'; ?>
  65  <rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
  66    <service>
  67      <engineName>b2evolution</engineName>
  68      <engineLink>http://b2evolution.net/</engineLink>
  69      <homePageLink><?php echo $baseurl ?></homePageLink>
  70      <apis>
  71        <api name="Movable Type" preferred="false" apiLink="<?php echo $xmlsrv_url; ?>xmlrpc.php" />
  72        <api name="MetaWeblog" preferred="true" apiLink="<?php echo $xmlsrv_url; ?>xmlrpc.php" />
  73        <api name="Blogger" preferred="false" apiLink="<?php echo $xmlsrv_url; ?>xmlrpc.php" />
  74      </apis>
  75    </service>
  76  </rsd>
  77  <?php
  78  exit;
  79  }
  80  
  81  // We can't display standard error messages. We must return XMLRPC responses.

  82  $DB->halt_on_error = false;
  83  $DB->show_errors = false;
  84  
  85  $post_default_title = ''; // posts submitted via the xmlrpc interface get that title

  86  
  87  /**

  88   * Used for logging, only if {@link $debug_xmlrpc_logging} is true

  89   *

  90   * @return boolean Have we logged?

  91   */
  92  function logIO($io,$msg)
  93  {
  94      global $debug_xmlrpc_logging;
  95  
  96      if( ! $debug_xmlrpc_logging )
  97      {
  98          return false;
  99      }
 100  
 101      $date = date('Y-m-d H:i:s ');
 102      $iot = ($io == 'I') ? ' Input: ' : ' Output: ';
 103  
 104      $fp = fopen( dirname(__FILE__).'/xmlrpc.log', 'a+' );
 105      fwrite($fp, $date.$iot.$msg."\n");
 106      fclose($fp);
 107  
 108      return true;
 109  }
 110  
 111  
 112  /**

 113   * Returns a string replaced by stars, for passwords.

 114   *

 115   * @param string the source string

 116   * @return string same length, but only stars

 117   */
 118  function starify( $string )
 119  {
 120      return str_repeat( '*', strlen( $string ) );
 121  }
 122  
 123  $b2newpost_doc='Adds a post, blogger-api like, +title +category +postdate';
 124  $b2newpost_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcBoolean, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 125  /**

 126   * b2.newPost. Adds a post, blogger-api like, +title +category +postdate.

 127   *

 128   * b2 API

 129   *

 130   * @param xmlrpcmsg XML-RPC Message

 131   *                    0 ?

 132   *                    1 ?

 133   *                    2 username (string): Login for a Blogger user who is member of the blog.

 134   *                    3 password (string): Password for said username.

 135   *                    4 content (string): The content of the post.

 136   *                    5 publish (boolean): If set to true, the post will be published immediately.

 137   *                    6 title (string): The title of the post.

 138   *                    7 category (string): The internal name of the category you want to post the post into.

 139   *                    8 date (string): This is the date that will be shown in the post, give "" for current date.

 140   * @return xmlrpcresp XML-RPC Response

 141   */
 142  function b2newpost($m)
 143  {
 144      global $xmlrpcerruser; // import user errcode value

 145      global $DB;
 146      global $Settings, $Messages;
 147  
 148      $username = $m->getParam(2);
 149      $username = $username->scalarval();
 150  
 151      $password = $m->getParam(3);
 152      $password = $password->scalarval();
 153  
 154      $content = $m->getParam(4);
 155      $content = $content->scalarval();
 156  
 157      $post_title = $m->getParam(6);
 158      $post_title = $post_title->scalarval();
 159  
 160      $category = $m->getParam(7);
 161      $category = $category->scalarval();
 162  
 163      $postdate = $m->getParam(8);
 164      $postdate = $postdate->scalarval();
 165  
 166      if( ! user_pass_ok($username,$password) )
 167      {
 168          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 169                       'Wrong username/password combination '.$username.' / '.starify($password));
 170      }
 171  
 172      $UserCache = & get_Cache( 'UserCache' );
 173      $current_User = & $UserCache->get_by_login( $username );
 174  
 175      // Check if category exists

 176      if( get_the_category_by_ID( $category, false ) === false )
 177      { // Cat does not exist:
 178          return new xmlrpcresp(0, $xmlrpcerruser+5, 'Requested category does not exist.'); // user error 5

 179      }
 180  
 181      $blog_ID = get_catblog($category);
 182  
 183      // Check permission:

 184      if( ! $current_User->check_perm( 'blog_post_statuses', 'published', false, $blog_ID ) )
 185      {
 186          return new xmlrpcresp(0, $xmlrpcerruser+2, 'Permission denied.'); // user error 2

 187      }
 188  
 189      if( $postdate != '' )
 190      {
 191          $now = $postdate;
 192      }
 193      else
 194      {
 195          $now = date('Y-m-d H:i:s', (time() + $Settings->get('time_difference')));
 196      }
 197  
 198      // CHECK and FORMAT content

 199      $post_title = format_to_post($post_title, 0, 0);
 200      $content = format_to_post($content, 0, 0);
 201  
 202      if( $errstring = $Messages->get_string( 'Cannot post, please correct these errors:', '' ) )
 203      {
 204          return new xmlrpcresp(0, $xmlrpcerruser+6, $errstring ); // user error 6

 205      }
 206  
 207      // INSERT NEW POST INTO DB:

 208      $edited_Item = & new Item();
 209      $post_ID = $edited_Item->insert( $current_User->ID, $post_title, $content, $now, $category, array(), 'published', $current_User->locale );
 210      if( $DB->error )
 211      { // DB error
 212          return new xmlrpcresp(0, $xmlrpcerruser+9, 'DB error: '.$DB->last_error ); // user error 9

 213      }
 214  
 215      logIO( 'O', 'Handling notifications...' );
 216      // Execute or schedule notifications & pings:

 217      $edited_Item->handle_post_processing();
 218  
 219      return new xmlrpcresp(new xmlrpcval($post_ID));
 220  }
 221  
 222  
 223  
 224  
 225  $b2getcategories_doc='given a blogID, gives a struct that list categories in that blog, using categoryID and categoryName. categoryName is there so the user would choose a category name from the client, rather than just a number. however, when using b2.newPost, only the category ID number should be sent.';
 226  $b2getcategories_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 227  /**

 228   * b2.getCategories

 229   *

 230   * B2 API

 231   *

 232   * Gets also used for mt.getCategoryList. Is this correct?

 233   *

 234   * @param xmlrpcmsg XML-RPC Message

 235   *                    0 blogid (string): Unique identifier of the blog to query

 236   *                    1 username (string): Login for a Blogger user who is member of the blog.

 237   *                    2 password (string): Password for said username.

 238   * @return xmlrpcresp XML-RPC Response

 239   */
 240  function b2getcategories( $m )
 241  {
 242      return _b2_or_mt_get_categories('b2', $m);
 243  }
 244  
 245  
 246  
 247  
 248  $b2_getPostURL_doc = 'Given a blog ID, username, password, and a post ID, returns the URL to that post.';
 249  $b2_getPostURL_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 250  /**

 251   * b2.getPostURL

 252   *

 253   * B2 API

 254   *

 255   * @param xmlrpcmsg XML-RPC Message

 256   *                    0 blogid (string): Unique identifier of the blog to query

 257   *                    1 ?

 258   *                    2 username (string): Login for a Blogger user who is member of the blog.

 259   *                    3 password (string): Password for said username.

 260   *                    4 post_ID (string): Post to query

 261   * @return xmlrpcresp XML-RPC Response

 262   */
 263  function b2_getPostURL($m)
 264  {
 265      global $xmlrpcerruser;
 266      global $siteurl;
 267  
 268      $blog_ID = $m->getParam(0);
 269      $blog_ID = $blog_ID->scalarval();
 270  
 271      $username = $m->getParam(2);
 272      $username = $username->scalarval();
 273  
 274      $password = $m->getParam(3);
 275      $password = $password->scalarval();
 276  
 277      $post_ID = $m->getParam(4);
 278      $post_ID = intval($post_ID->scalarval());
 279  
 280      if( ! user_pass_ok($username, $password) )
 281      {
 282          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 283                       'Wrong username/password combination '.$username.' / '.starify($password));
 284      }
 285  
 286      $UserCache = & get_Cache( 'UserCache' );
 287      $current_User = & $UserCache->get_by_login( $username );
 288  
 289      // Check permission:

 290      if( ! $current_User->check_perm( 'blog_ismember', 1, false, $blog_ID ) )
 291      {
 292          return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2
 293                  'Permission denied.' );
 294      }
 295  
 296      $ItemCache = & get_Cache( 'ItemCache' );
 297      if( ( $Item = & $ItemCache->get_by_ID( $post_ID ) ) === false )
 298      { // Post does not exist
 299          return new xmlrpcresp(0, $xmlrpcerruser+7,
 300                          'This post ID ('.$post_ID.') does not correspond to any post here.' );
 301      }
 302  
 303      return new xmlrpcresp( new xmlrpcval( $Item->get_permanent_url() ) );
 304  }
 305  
 306  
 307  
 308  
 309  $bloggernewpost_doc = 'Adds a post, blogger-api like';
 310  $bloggernewpost_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcBoolean));
 311  /**

 312   * blogger.newPost makes a new post to a designated blog.

 313   *

 314   * BLOGGER API

 315   *

 316   * Optionally, will publish the blog after making the post. (In b2evo, this means the

 317   * new post will be in 'published' state).

 318   * On success, it returns the unique ID of the new post (usually a seven-digit number

 319   * at this time).

 320   * On error, it will return some error message.

 321   *

 322   * @see http://www.blogger.com/developers/api/1_docs/xmlrpc_newPost.html

 323   *

 324   * @param xmlrpcmsg XML-RPC Message

 325   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 326   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 327   *                    1 blogid (string): Unique identifier of the blog the post will be added to.

 328   *                        Currently ignored in b2evo, in favor of the category.

 329   *                    2 username (string): Login for a Blogger user who has permission to post to the blog.

 330   *                    3 password (string): Password for said username.

 331   *                    4 content (string): Contents of the post.

 332   *                    5 publish (boolean): If true, the blog will be published immediately after the

 333   *                        post is made. (In b2evo,this means, the new post will be in 'published' state,

 334   *                        otherwise it would be in draft state).

 335   * @return xmlrpcresp XML-RPC Response

 336   */
 337  function bloggernewpost( $m )
 338  {
 339      global $xmlrpcerruser; // import user errcode value

 340      global $DB;
 341      global $Settings, $Messages;
 342  
 343      logIO('I','Called function: blogger.newPost');
 344  
 345      $username = $m->getParam(2);
 346      $password = $m->getParam(3);
 347      $content  = $m->getParam(4);
 348      $publish  = $m->getParam(5);
 349  
 350      $username = $username->scalarval();
 351      $password = $password->scalarval();
 352      $content = $content->scalarval();
 353      $publish = $publish->scalarval();
 354      $status = $publish ? 'published' : 'draft';
 355      logIO('I',"Publish: $publish -> Status: $status");
 356  
 357      if( !user_pass_ok($username,$password) )
 358      {
 359          logIO('O', "Wrong username/password combination <strong>$username / $password</strong>");
 360          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 361                       'Wrong username/password combination '.$username.' / '.starify($password));
 362      }
 363  
 364      $UserCache = & get_Cache( 'UserCache' );
 365      $current_User = & $UserCache->get_by_login( $username );
 366  
 367      $post_categories = xmlrpc_getpostcategories($content);
 368  
 369      if( ! $post_categories )
 370      { // There were no categories passed in the content:
 371          return new xmlrpcresp(0, $xmlrpcerruser+5, 'No category given.'); // user error 5

 372      }
 373  
 374      $main_cat = array_shift($post_categories);
 375      logIO('I', 'Main cat: '.$main_cat);
 376  
 377      // Check if category exists

 378      if( get_the_category_by_ID( $main_cat, false ) === false )
 379      { // Cat does not exist:
 380          // fp> TODO use $Blog->get_default_cat_ID();

 381          return new xmlrpcresp(0, $xmlrpcerruser+5, 'Requested category does not exist.'); // user error 5

 382      }
 383  
 384      $blog_ID = get_catblog($main_cat);
 385  
 386      // Check permission:

 387      if( ! $current_User->check_perm( 'blog_post_statuses', $status, false, $blog_ID ) )
 388      {
 389          return new xmlrpcresp(0, $xmlrpcerruser+2, 'Permission denied.'); // user error 2

 390      }
 391  
 392      // Extract <title> from content

 393      $post_title = xmlrpc_getposttitle( $content );
 394  
 395      // cleanup content from extra tags like <category> and <title>:

 396      $content = xmlrpc_removepostdata( $content );
 397  
 398      $now = date('Y-m-d H:i:s', (time() + $Settings->get('time_difference')));
 399  
 400      // CHECK and FORMAT content

 401      $post_title = format_to_post($post_title,0,0);
 402      $content = format_to_post($content,0,0);
 403  
 404      if( $errstring = $Messages->get_string( 'Cannot post, please correct these errors:', '' ) )
 405      {
 406          return new xmlrpcresp(0, $xmlrpcerruser+6, $errstring ); // user error 6

 407      }
 408  
 409      // INSERT NEW POST INTO DB:

 410      $edited_Item = & new Item();
 411      $edited_Item->set('title', $post_title);
 412      $edited_Item->set('content', $content);
 413      $edited_Item->set('datestart', $now);
 414      $edited_Item->set('main_cat_ID', $main_cat);
 415      $edited_Item->set('extra_cat_IDs', $post_categories);
 416      $edited_Item->set('status', $status);
 417      $edited_Item->set('locale', $current_User->locale );
 418      $edited_Item->set_creator_User($current_User);
 419      $edited_Item->dbinsert();
 420  
 421      if( ! $edited_Item->ID )
 422      { // DB error
 423          return new xmlrpcresp(0, $xmlrpcerruser+9, 'Error while inserting item: '.$DB->last_error ); // user error 9

 424      }
 425  
 426      logIO('O', "Posted ! ID: $edited_Item->ID");
 427  
 428      logIO( 'O', 'Handling notifications...' );
 429      // Execute or schedule notifications & pings:

 430      $edited_Item->handle_post_processing();
 431  
 432      logIO("O","All done.");
 433  
 434      return new xmlrpcresp(new xmlrpcval($edited_Item->ID));
 435  }
 436  
 437  
 438  $bloggereditpost_doc='Edits a post, blogger-api like';
 439  $bloggereditpost_sig=array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcBoolean));
 440  /**

 441   * blogger.editPost changes the contents of a given post.

 442   *

 443   * Optionally, will publish the blog the post belongs to after changing the post.

 444   * (In b2evo, this means the changed post will be moved to published state).

 445   * On success, it returns a boolean true value.

 446   * On error, it will return a fault with an error message.

 447   *

 448   * @see http://www.blogger.com/developers/api/1_docs/xmlrpc_editPost.html

 449   *

 450   * @param xmlrpcmsg XML-RPC Message

 451   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 452   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 453   *                    1 postid (string): Unique identifier of the post to be changed.

 454   *                    2 username (string): Login for a Blogger user who has permission to edit the given

 455   *                        post (either the user who originally created it or an admin of the blog).

 456   *                    3 password (string): Password for said username.

 457   *                    4 content (string): New content of the post.

 458   *                    5 publish (boolean): If true, the blog will be published immediately after the

 459   *                        post is made. (In b2evo,this means, the new post will be in 'published' state,

 460   *                        otherwise it would be in draft state).

 461   * @return xmlrpcresp XML-RPC Response

 462   *

 463   * @todo check current status and permission on it

 464   */
 465  function bloggereditpost($m)
 466  {
 467      global $xmlrpcerruser; // import user errcode value

 468      global $DB;
 469      global $Messages;
 470  
 471      logIO('I','Called function: blogger.editPost');
 472  
 473      // return new xmlrpcresp(0, $xmlrpcerruser+50, 'bloggereditpost' );

 474  
 475      $post_ID = $m->getParam(1);
 476      $post_ID = $post_ID->scalarval();
 477  
 478      $username = $m->getParam(2);
 479      $username = $username->scalarval();
 480  
 481      $password = $m->getParam(3);
 482      $password = $password->scalarval();
 483  
 484      if( !user_pass_ok($username, $password) )
 485      {
 486          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 487                       'Wrong username/password combination '.$username.' / '.starify($password));
 488      }
 489  
 490      $ItemCache = & get_Cache( 'ItemCache' );
 491      if( ! ($edited_Item = & $ItemCache->get_by_ID( $post_ID ) ) )
 492      {
 493          return new xmlrpcresp(0, $xmlrpcerruser+7, "No such post (#$post_ID)."); // user error 7

 494      }
 495  
 496      $content = $m->getParam(4);
 497      $content = $content->scalarval();
 498      $content = str_replace("\n",'',$content); // Tor - kludge to fix bug in xmlrpc libraries

 499      // WARNING: the following debug MAY produce a non valid response (XML comment containing emebedded <!-- more -->)

 500      // xmlrpc_debugmsg( 'New content: '.$content  );

 501  
 502      $publish = $m->getParam(5);
 503      $publish = $publish->scalarval();
 504      $status = $publish ? 'published' : 'draft';
 505      logIO('I',"Publish: $publish -> Status: $status");
 506  
 507      $UserCache = & get_Cache( 'UserCache' );
 508      $current_User = & $UserCache->get_by_login( $username );
 509  
 510      $post_categories = xmlrpc_getpostcategories($content);
 511      if( $post_categories )
 512      {
 513          $main_cat = array_shift($post_categories);
 514  
 515          if( get_the_category_by_ID( $main_cat, false ) === false )
 516          { // requested Cat does not exist:
 517              return new xmlrpcresp(0, $xmlrpcerruser+5, 'Requested main category does not exist.'); // user error 5

 518          }
 519      }
 520      else
 521      {
 522          $main_cat = $edited_Item->main_cat_ID;
 523      }
 524  
 525      $blog_ID = get_catblog($main_cat);
 526  
 527      // Check permission:

 528      if( ! $current_User->check_perm( 'blog_post_statuses', $status, false, $blog_ID ) )
 529      {
 530          return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2
 531                  'Permission denied.' );
 532      }
 533  
 534      $post_title = xmlrpc_getposttitle($content);
 535      $content = xmlrpc_removepostdata($content);
 536  
 537      // CHECK and FORMAT content

 538      $post_title = format_to_post($post_title,0,0);
 539      $content = format_to_post($content,0,0);
 540  
 541      if( $errstring = $Messages->get_string( 'Cannot update post, please correct these errors:', '' ) )
 542      {
 543          return new xmlrpcresp(0, $xmlrpcerruser+6, $errstring ); // user error 6

 544      }
 545  
 546      // UPDATE POST IN DB:

 547      $edited_Item->set( 'title', $post_title );
 548      $edited_Item->set( 'content', $content );
 549      if( $post_categories )
 550      { // update cats, if given:
 551          $edited_Item->set( 'main_cat_ID', $main_cat );
 552          $edited_Item->set( 'extra_cat_IDs', array($post_categories) );
 553      }
 554      $edited_Item->set( 'status', $status );
 555      $edited_Item->dbupdate();
 556  
 557      if( $DB->error )
 558      { // DB error
 559          return new xmlrpcresp(0, $xmlrpcerruser+9, 'DB error: '.$DB->last_error ); // user error 9

 560      }
 561  
 562      logIO( 'O', 'Handling notifications...' );
 563      // Execute or schedule notifications & pings:

 564      $edited_Item->handle_post_processing();
 565  
 566      return new xmlrpcresp(new xmlrpcval("1", "boolean"));
 567  }
 568  
 569  
 570  
 571  
 572  $bloggerdeletepost_doc = 'Deletes a post, blogger-api like';
 573  $bloggerdeletepost_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 574  /**

 575   * blogger.editPost deletes a given post.

 576   *

 577   * This API call is not documented on

 578   * {@link http://www.blogger.com/developers/api/1_docs/}

 579   *

 580   * @param xmlrpcmsg XML-RPC Message

 581   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 582   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 583   *                    1 postid (string): Unique identifier of the post to be deleted.

 584   *                    2 username (string): Login for a Blogger user who has permission to edit the given

 585   *                        post (either the user who originally created it or an admin of the blog).

 586   *                    3 password (string): Password for said username.

 587   * @return xmlrpcresp XML-RPC Response

 588   */
 589  function bloggerdeletepost($m)
 590  {
 591      global $xmlrpcerruser; // import user errcode value

 592      global $DB;
 593  
 594      $post_ID = $m->getParam(1);
 595      $post_ID = $post_ID->scalarval();
 596      // logIO("O","finished getting post_id ...".$post_ID);

 597  
 598      $username = $m->getParam(2);
 599      $username = $username->scalarval();
 600  
 601      $password = $m->getParam(3);
 602      $password = $password->scalarval();
 603  
 604      if( ! user_pass_ok( $username, $password ) )
 605      {
 606          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 607                       'Wrong username/password combination '.$username.' / '.starify($password));
 608      }
 609  
 610      $ItemCache = & get_Cache( 'ItemCache' );
 611      if( ! ($edited_Item = & $ItemCache->get_by_ID( $post_ID, false ) ) )
 612      {
 613          return new xmlrpcresp(0, $xmlrpcerruser+7, 'No such post.');    // user error 7

 614      }
 615  
 616      $UserCache = & get_Cache( 'UserCache' );
 617      $current_User = & $UserCache->get_by_login( $username );
 618  
 619      // Check permission:

 620      if( ! $current_User->check_perm( 'blog_del_post', 'any', false, $edited_Item->blog_ID ) )
 621      {
 622          return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2
 623                  'Permission denied.');
 624      }
 625  
 626      // DELETE POST FROM DB:

 627      $edited_Item->dbdelete();
 628      if( $DB->error )
 629      { // DB error
 630          return new xmlrpcresp(0, $xmlrpcerruser+9, 'DB error: '.$DB->last_error ); // user error 9

 631      }
 632  
 633      return new xmlrpcresp(new xmlrpcval(1));
 634  }
 635  
 636  
 637  
 638  $bloggergetusersblogs_doc='returns the user\'s blogs - this is a dummy function, just so that BlogBuddy and other blogs-retrieving apps work';
 639  $bloggergetusersblogs_sig=array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 640  /**

 641   * blogger.getUsersBlogs returns information about all the blogs a given user is a member of.

 642   *

 643   * Data is returned as an array of <struct>'s containing the ID (blogid), name (blogName),

 644   * and URL (url) of each blog.

 645   *

 646   * Non official: Also return a boolean stating wether or not the user can edit th eblog templates

 647   * (isAdmin).

 648   *

 649   * see {@link http://www.blogger.com/developers/api/1_docs/xmlrpc_getUsersBlogs.html}

 650   *

 651   * @param xmlrpcmsg XML-RPC Message

 652   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 653   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 654   *                    1 username (string): Login for the Blogger user who's blogs will be retrieved.

 655   *                    2 password (string): Password for said username.

 656   *                        (currently not required by b2evo)

 657   * @return xmlrpcresp XML-RPC Response, an array of <struct>'s containing for each blog:

 658   *                    - ID (blogid),

 659   *                    - name (blogName),

 660   *                    - URL (url),

 661   *                    - bool: can user edit template? (isAdmin).

 662   */
 663  function bloggergetusersblogs($m)
 664  {
 665      global $xmlrpcerruser;
 666      global $baseurl;
 667  
 668      $username = $m->getParam(1);
 669      $username = $username->scalarval();
 670  
 671      $password = $m->getParam(2);
 672      $password = $password->scalarval();
 673      logIO("O","entered bloggergetusersblogs.");
 674  
 675  
 676      if( ! user_pass_ok($username,$password) )
 677      {
 678          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 679                       'Wrong username/password combination '.$username.' / '.starify($password));
 680      }
 681      logIO("O","user approved.");
 682  
 683  
 684      $UserCache = & get_Cache( 'UserCache' );
 685      $current_User = & $UserCache->get_by_login( $username );
 686      logIO("O","Got Current user (ID ".$current_User->ID.')');
 687  
 688  
 689      $resp_array = array();
 690  
 691      $BlogCache = & get_Cache( 'BlogCache' );
 692  
 693      $blog_array = $BlogCache->load_user_blogs( 'blog_ismember', 'view', $current_User->ID, 'ID' );
 694  
 695      foreach( $blog_array as $l_blog_ID )
 696      {    // Loop through all blogs that match the requested permission:
 697  
 698          /**

 699           * @var Blog

 700           */
 701          $l_Blog = & $BlogCache->get_by_ID( $l_blog_ID );
 702  
 703          logIO("O","Current user IS a member of this blog.".$l_blog_ID);
 704  
 705          $resp_array[] = new xmlrpcval( array(
 706                      "blogid" => new xmlrpcval( $l_blog_ID ),
 707                      "blogName" => new xmlrpcval( $l_Blog->get('shortname') ),
 708                      "url" => new xmlrpcval( $l_Blog->gen_blogurl() ),
 709                      "isAdmin" => new xmlrpcval( $current_User->check_perm( 'templates', 'any' ), 'boolean')
 710                                                  ), 'struct');
 711      }
 712  
 713      $resp = new xmlrpcval($resp_array, 'array');
 714  
 715      return new xmlrpcresp($resp);
 716  }
 717  
 718  
 719  
 720  
 721  $bloggergetuserinfo_doc='gives the info about a user';
 722  $bloggergetuserinfo_sig=array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 723  /**

 724   * blogger.getUserInfo returns returns a struct containing user info.

 725   *

 726   * Data returned: userid, firstname, lastname, nickname, email, and url.

 727   *

 728   * see {@link http://www.blogger.com/developers/api/1_docs/xmlrpc_getUserInfo.html}

 729   *

 730   * @param xmlrpcmsg XML-RPC Message

 731   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 732   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 733   *                    1 username (string): Login for the Blogger user who's blogs will be retrieved.

 734   *                    2 password (string): Password for said username.

 735   *                        (currently not required by b2evo)

 736   * @return xmlrpcresp XML-RPC Response, a <struct> containing:

 737   *                    - userid,

 738   *                    - firstname,

 739   *                    - lastname,

 740   *                    - nickname,

 741   *                    - email,

 742   *                    - url

 743   */
 744  function bloggergetuserinfo($m)
 745  {
 746      global $xmlrpcerruser;
 747  
 748      $username = $m->getParam(1);
 749      $username = $username->scalarval();
 750  
 751      $password = $m->getParam(2);
 752      $password = $password->scalarval();
 753  
 754      $UserCache = & get_Cache( 'UserCache' );
 755      $User = & $UserCache->get_by_login( $username );
 756  
 757      if( user_pass_ok( $username, $password) )
 758      {
 759          $struct = new xmlrpcval( array(
 760                                                              'nickname' => new xmlrpcval( $User->get('nickname') ),
 761                                                              'userid' => new xmlrpcval( $User->ID ),
 762                                                              'url' => new xmlrpcval( $User->get('url') ),
 763                                                              'email' => new xmlrpcval( $User->get('email') ),
 764                                                              'lastname' => new xmlrpcval( $User->get('lastname') ),
 765                                                              'firstname' => new xmlrpcval( $User->get('firstname') )
 766                                                              ), 'struct' );
 767          $resp = $struct;
 768          return new xmlrpcresp($resp);
 769      }
 770      else
 771      {
 772          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 773                       'Wrong username/password combination '.$username.' / '.starify($password));
 774      }
 775  }
 776  
 777  
 778  
 779  
 780  $bloggergetpost_doc = 'fetches a post, blogger-api like';
 781  $bloggergetpost_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 782  /**

 783   * blogger.getPost retieves a given post.

 784   *

 785   * This API call is not documented on

 786   * {@link http://www.blogger.com/developers/api/1_docs/}

 787   *

 788   * @param xmlrpcmsg XML-RPC Message

 789   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 790   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 791   *                    1 postid (string): Unique identifier of the post to be deleted.

 792   *                    2 username (string): Login for a Blogger user who has permission to edit the given

 793   *                        post (either the user who originally created it or an admin of the blog).

 794   *                    3 password (string): Password for said username.

 795   * @return xmlrpcresp XML-RPC Response

 796   */
 797  function bloggergetpost($m)
 798  {
 799      global $xmlrpcerruser;
 800  
 801      $post_ID = $m->getParam(1);
 802      $post_ID = $post_ID->scalarval();
 803  
 804      $username = $m->getParam(2);
 805      $username = $username->scalarval();
 806  
 807      $password = $m->getParam(3);
 808      $password = $password->scalarval();
 809  
 810      if( user_pass_ok($username,$password) )
 811      {
 812          $postdata = get_postdata($post_ID);
 813  
 814          if( $postdata['Date'] != '' )
 815          {
 816              $post_date = mysql2date("U", $postdata["Date"]);
 817              $post_date = gmdate("Ymd", $post_date)."T".gmdate("H:i:s", $post_date);
 818  
 819              $content    = "<title>".$postdata["Title"]."</title>";
 820              $content .= "<category>".$postdata["Category"]."</category>";
 821              $content .= $postdata["Content"];
 822  
 823              $struct = new xmlrpcval(array("userid" => new xmlrpcval($postdata["Author_ID"]),
 824                                              "dateCreated" => new xmlrpcval($post_date,"dateTime.iso8601"),
 825                                              "content" => new xmlrpcval($content),
 826                                              "postid" => new xmlrpcval($postdata["ID"])
 827                                              ),"struct");
 828  
 829              $resp = $struct;
 830              return new xmlrpcresp($resp);
 831          }
 832          else
 833          {
 834          return new xmlrpcresp(0, $xmlrpcerruser+7, // user error 7
 835                       "No such post #$post_ID");
 836          }
 837      }
 838      else
 839      {
 840          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 841                       'Wrong username/password combination '.$username.' / '.starify($password));
 842      }
 843  }
 844  
 845  
 846  
 847  
 848  $bloggergetrecentposts_doc = 'fetches X most recent posts, blogger-api like';
 849  $bloggergetrecentposts_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcInt));
 850  /**

 851   * blogger.getRecentPosts retieves X most recent posts.

 852   *

 853   * This API call is not documented on

 854   * {@link http://www.blogger.com/developers/api/1_docs/}

 855   *

 856   * @param xmlrpcmsg XML-RPC Message

 857   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 858   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 859   *                    1 blogid (string): Unique identifier of the blog the post will be added to.

 860   *                        Currently ignored in b2evo, in favor of the category.

 861   *                    2 username (string): Login for a Blogger user who has permission to edit the given

 862   *                        post (either the user who originally created it or an admin of the blog).

 863   *                    3 password (string): Password for said username.

 864   *                    4 numposts (integer): number of posts to retrieve.

 865   * @return xmlrpcresp XML-RPC Response

 866   */
 867  function bloggergetrecentposts( $m )
 868  {
 869      global $xmlrpcerruser, $DB;
 870  
 871      $blog_ID = $m->getParam(1);
 872      $blog_ID = $blog_ID->scalarval();
 873  
 874      $username = $m->getParam(2);
 875      $username = $username->scalarval();
 876  
 877      $password = $m->getParam(3);
 878      $password = $password->scalarval();
 879  
 880      $numposts = $m->getParam(4);
 881      $numposts = $numposts->scalarval();
 882  
 883      if( ! user_pass_ok($username, $password) )
 884      {
 885          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 886                       'Wrong username/password combination '.$username.' / '.starify($password));
 887      }
 888  
 889      $UserCache = & get_Cache( 'UserCache' );
 890      $current_User = & $UserCache->get_by_login( $username );
 891  
 892      // Check permission:

 893      if( ! $current_User->check_perm( 'blog_ismember', 1, false, $blog_ID ) )
 894      {
 895          return new xmlrpcresp(0, $xmlrpcerruser+2, 'Permission denied.' ); // user error 2

 896      }
 897  
 898  
 899      $BlogCache = & get_Cache( 'BlogCache' );
 900      $Blog = & $BlogCache->get_by_ID( $blog_ID );
 901  
 902      // Get the posts to display:

 903      $MainList = & new ItemList2( $Blog, NULL, NULL, $numposts );
 904  
 905      $MainList->set_filters( array(
 906              'visibility_array' => array( 'published', 'protected', 'private', 'draft', 'deprecated', 'redirected' ),
 907              'order' => 'DESC',
 908              'unit' => 'posts',
 909          ) );
 910  
 911      // Run the query:

 912      $MainList->query();
 913  
 914  
 915      xmlrpc_debugmsg( 'Items:'.$MainList->result_num_rows );
 916  
 917      $data = array();
 918      while( $Item = & $MainList->get_item() )
 919      {
 920          xmlrpc_debugmsg( 'Item:'.$Item->title.
 921                                              ' - Issued: '.$Item->issue_date.
 922                                              ' - Modified: '.$Item->mod_date );
 923  
 924          $post_date = mysql2date("U", $Item->issue_date);
 925          $post_date = gmdate("Ymd", $post_date)."T".gmdate("H:i:s", $post_date);
 926  
 927          $content    = '<title>'.$Item->title.'</title>';
 928          $content .= '<category>'.$Item->main_cat_ID.'</category>';
 929          $content .= $Item->content;
 930  
 931          // Load Item's creator User:

 932          $Item->get_creator_User();
 933          $authorname = $Item->creator_User->get('preferredname');
 934  
 935          $data[] = new xmlrpcval(array(
 936                                      "authorName" => new xmlrpcval($authorname),
 937                                      "userid" => new xmlrpcval($Item->creator_user_ID),
 938                                      "dateCreated" => new xmlrpcval($post_date,"dateTime.iso8601"),
 939                                      "content" => new xmlrpcval($content),
 940                                      "postid" => new xmlrpcval($Item->ID)
 941                                      ),"struct");
 942      }
 943  
 944      $resp = new xmlrpcval($data, "array");
 945  
 946      return new xmlrpcresp($resp);
 947  
 948  }
 949  
 950  
 951  
 952  
 953  
 954  $bloggergettemplate_doc = 'returns the default template file\'s code';
 955  $bloggergettemplate_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
 956  /**

 957   * blogger.getTemplate returns text of the main or archive index template for a given blog.

 958   *

 959   * Currently, in b2evo, this will return the templates of the 'custom' skin.

 960   *

 961   * see {@link http://www.blogger.com/developers/api/1_docs/xmlrpc_getTemplate.html}

 962   *

 963   * @param xmlrpcmsg XML-RPC Message

 964   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

 965   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

 966   *                    1 blogid (string): Unique identifier of the blog who's template is to be returned.

 967   *                    2 username (string): Login for a Blogger who has admin permission on given blog.

 968   *                    3 password (string): Password for said username.

 969   *                    4 templateType (string): Determines which of the blog's templates will be returned.

 970   *                        Currently, either "main" or "archiveIndex".

 971   * @return xmlrpcresp XML-RPC Response

 972   */
 973  function bloggergettemplate($m)
 974  {
 975      global $xmlrpcerruser;
 976  
 977      $blog_ID = $m->getParam(1);
 978      $blog_ID = $blog_ID->scalarval();
 979  
 980      $username = $m->getParam(2);
 981      $username = $username->scalarval();
 982  
 983      $password = $m->getParam(3);
 984      $password = $password->scalarval();
 985  
 986      $templateType = $m->getParam(4);
 987      $templateType = $templateType->scalarval();
 988  
 989      if( !user_pass_ok($username, $password) )
 990      {
 991          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
 992                       'Wrong username/password combination '.$username.' / '.starify($password));
 993      }
 994  
 995      $UserCache = & get_Cache( 'UserCache' );
 996      $current_User = & $UserCache->get_by_login( $username );
 997  
 998      // Check permission:

 999      if( ! $current_User->check_perm( 'templates' ) )
1000      {
1001          return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2
1002                  'Permission denied.');
1003      }
1004  
1005      // Determine the edit folder:

1006      $edit_folder = $skins_path.'custom/';
1007  
1008      if ($templateType == "main")
1009      {
1010          $file = $edit_folder.'index.main.php';
1011      }
1012      elseif ($templateType == "archiveIndex")
1013      {
1014          $file = $edit_folder.'_arcdir.php';
1015      }
1016      else return; // TODO: handle this cleanly

1017  
1018      $f = fopen($file,"r");
1019      $content = fread($f,filesize($file));
1020      fclose($file);
1021  
1022      $content = str_replace("\n","\r\n",$content); // so it is actually editable with a windows/mac client, instead of being returned as a looooooooooong line of code

1023  
1024      return new xmlrpcresp(new xmlrpcval("$content"));
1025  
1026  }
1027  
1028  
1029  
1030  $bloggersettemplate_doc = 'saves the default template file\'s code';
1031  $bloggersettemplate_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
1032  /**

1033   * blogger.setTemplate changes the template for a given blog.

1034   *

1035   * Can change either main or archive index template.

1036   *

1037   * Currently, in b2evo, this will change the templates of the 'custom' skin.

1038   *

1039   * see {@link http://www.blogger.com/developers/api/1_docs/xmlrpc_getTemplate.html}

1040   *

1041   * @param xmlrpcmsg XML-RPC Message

1042   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

1043   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

1044   *                    1 blogid (string): Unique identifier of the blog who's template is to be returned.

1045   *                    2 username (string): Login for a Blogger who has admin permission on given blog.

1046   *                    3 password (string): Password for said username.

1047   *                    4 template (string): The text for the new template (usually mostly HTML).

1048   *                    5 templateType (string): Determines which of the blog's templates will be returned.

1049   *                        Currently, either "main" or "archiveIndex".

1050   * @return xmlrpcresp XML-RPC Response

1051   */
1052  function bloggersettemplate( $m )
1053  {
1054      global $xmlrpcerruser, $blogfilename;
1055  
1056      $blog_ID = $m->getParam(1);
1057      $blog_ID = $blog_ID->scalarval();
1058  
1059      $username = $m->getParam(2);
1060      $username = $username->scalarval();
1061  
1062      $password = $m->getParam(3);
1063      $password = $password->scalarval();
1064  
1065      $template = $m->getParam(4);
1066      $template = $template->scalarval();
1067  
1068      $templateType = $m->getParam(5);
1069      $templateType = $templateType->scalarval();
1070  
1071      if( !user_pass_ok($username, $password) )
1072      {
1073          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1074                       'Wrong username/password combination '.$username.' / '.starify($password));
1075      }
1076  
1077      $UserCache = & get_Cache( 'UserCache' );
1078      $current_User = & $UserCache->get_by_login( $username );
1079  
1080      // Check permission:

1081      if( ! $current_User->check_perm( 'templates' ) )
1082      {
1083          return new xmlrpcresp(0, $xmlrpcerruser+2, // user error 2
1084                  'Permission denied.');
1085      }
1086  
1087      // Determine the edit folder:

1088      $edit_folder = $skins_path.'custom/';
1089  
1090      if( $templateType == 'main' )
1091      {
1092          $file = $edit_folder.'index.main.php';
1093      }
1094      elseif ($templateType == "archiveIndex")
1095      {
1096          $file = $edit_folder.'_arcdir.php';
1097      }
1098      else return; // TODO: handle this cleanly

1099  
1100      $f = fopen($file,"w+");
1101      fwrite($f, $template);
1102      fclose($file);
1103  
1104      return new xmlrpcresp(new xmlrpcval("1", "boolean"));
1105  }
1106  
1107  
1108  
1109  //---------- Tor Jan 2005 Metaweblog  API ----------------

1110  //

1111  //    Tor Dec 2004

1112  //

1113  // image upload

1114  //  image is supplied coded in the info struct as bits

1115  //

1116  // To do - do not overwrite existing pics with same name

1117  //        -    security, password etc.

1118  //

1119  //

1120  function mwnewMediaObject($m) {
1121      global $xmlrpcerruser; // import user errcode value

1122      global $Settings, $baseurl,$fileupload_allowedtypes;
1123  
1124      logIO("O","start of _newmediaobject...");
1125      $blogid = $m->getParam(0);
1126      $blogid = $blogid->scalarval();
1127      $username = $m->getParam(1);
1128      $username = $username->scalarval();
1129      $password = $m->getParam(2);
1130      $password = $password->scalarval();
1131      if( !user_pass_ok($username, $password) )
1132      {
1133          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1134                   'Wrong username/password combination '.$username.' / '.starify($password));
1135      }
1136      if( ! $Settings->get('upload_enabled') )
1137      {
1138          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1139                   'Object upload not allowed ');
1140      }
1141      $BlogCache = & get_Cache('BlogCache');
1142      $Blog = & $BlogCache->get_by_ID($blogid);
1143  
1144      // Get the main data - and decode it properly for the image - sorry, binary object

1145      $xcontent = $m->getParam(3);
1146      $contentstruct = xmlrpc_decode($xcontent);
1147      logIO("O", 'Got first contentstruct!'."\n");
1148  
1149      // This call seems to go wrong from Marsedit under certain circumstances - Tor 04012005

1150      $data = $contentstruct['bits']; // decoding was done transparantly by xmlrpclibs xmlrpc_decode

1151      logIO("O", 'Have decoded data data?'."\n");
1152  
1153      // TODO: check filesize

1154      $filename = $contentstruct['name'];
1155      logIO("O", 'Found filename ->'. $filename ."\n");
1156      $type = $contentstruct['type'];
1157      logIO("O", 'Done type ->'. $type ."\n");
1158      $data = $contentstruct['bits'];
1159      logIO("O", 'Done bits ' ."\n");
1160  
1161      // Split into path + name:

1162      $filepath = dirname($filename);
1163      $filename = basename($filename);
1164  
1165      $filepath_parts = explode('/', $filepath);
1166      if( in_array('..', $filepath_parts) )
1167      { // invalid relative path:
1168          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1169              'Invalid relative part in file path: '.$filepath);
1170      }
1171  
1172      // Check valid filename/extension:

1173      load_funcs('files/model/_file.funcs.php');
1174      if( $error_filename = validate_filename($filename) )
1175      {
1176          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1177              'Invalid objecttype for upload ('.$filename.'): '.$error_filename);
1178      }
1179  
1180      $fileupload_path = $Blog->get_media_dir();
1181      if( ! $fileupload_path )
1182      {
1183          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1184              'Error accessing Blog media directory.');
1185      }
1186  
1187      // Handle subdirs, if any:

1188      if( strlen($filepath) && $filepath != '.' )
1189      {
1190          $fileupload_path .= $filepath;
1191          if( ! mkdir_r(dirname($fileupload_path)) )
1192          {
1193              return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1194                  'Error creating sub directories: '.rel_path_to_base($fileupload_path));
1195          }
1196      }
1197  
1198      logIO("O", 'fileupload_path ->'. $fileupload_path ."\n");
1199      $fh = @fopen($fileupload_path.$filename, 'wb');
1200      logIO("O", 'Managed to open file ->'. $filename ."\n");
1201      if (!$fh)
1202      {
1203          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1204              'Error opening file for writing.');
1205      }
1206  
1207      logIO("O", 'Managed to open file for writing ->'. $fileupload_path.$filename."\n");
1208      $ok = @fwrite($fh, $data);
1209      @fclose($fh);
1210  
1211      if (!$ok)
1212      {
1213          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1214              'Error while writing to file.');
1215      }
1216  
1217      // chmod uploaded file:

1218      $oldumask = umask(0000);
1219      $chmod = $Settings->get('fm_default_chmod_file');
1220      @chmod($fileupload_path.$filename, octdec( $chmod ));
1221      umask($oldumask);
1222  
1223      $url = $Blog->get_media_url().$filepath.$filename;
1224      logIO("O", 'Full returned filename ->'. $fileupload_path . '/' . $filename ."\n");
1225      logIO("O", 'Full returned url ->'. $url ."\n");
1226  
1227      // - return URL as XML

1228      $urlstruct = new xmlrpcval(array(
1229              'url' => new xmlrpcval($url, 'string')
1230          ), 'struct');
1231      return new xmlrpcresp($urlstruct);
1232  }
1233  
1234  
1235  
1236  // metaWeblog.newMediaObject

1237  $mwnewMediaObject_sig = array(array(
1238      //  return type

1239      $xmlrpcStruct,        // "url" element
1240      // params

1241      $xmlrpcString,        // blogid
1242      $xmlrpcString,        // username
1243      $xmlrpcString,        // password
1244      $xmlrpcStruct        // 'name', 'type' and 'bits'
1245  ));
1246  $mwnewMediaObject_doc = 'Uploads a file to the media library of the blog';
1247  
1248  
1249  
1250  $mwnewpost_doc='Adds a post, blogger-api like, +title +category +postdate';
1251  $mwnewpost_sig =  array(array($xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcStruct,$xmlrpcBoolean));
1252  
1253  /**

1254   * mw.newPost

1255   *

1256   * mw API

1257   * Tor 2004

1258   *

1259   * NB! (Tor Feb 2005) status in metaweblog API speak dictates whether static html files are generated or not, so fairly misleading

1260   */
1261  function mwnewpost($m)
1262  {
1263      global $xmlrpcerruser; // import user errcode value

1264      global $DB;
1265      global $Settings;
1266  
1267      logIO("O","start of mwnewpost...");
1268  
1269      $blog_ID = $m->getParam(0);
1270      $blog_ID = $blog_ID->scalarval();
1271  
1272      $username = $m->getParam(1);
1273      $username = $username->scalarval();
1274      logIO("O","finished getting username ...");
1275      $password = $m->getParam(2);
1276      $password = $password->scalarval();
1277      logIO("O","finished getting password ...".starify($password));
1278  
1279      if( ! user_pass_ok($username,$password) )
1280      {
1281      logIO("O","error during checking password ...");
1282          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1283                       'Wrong username/password combination '.$username.' / '.starify($password));
1284      }
1285      logIO("O","finished checking password ...");
1286  
1287  
1288      $xcontent = $m->getParam(3);
1289  //    $xcontent = $xcontent->scalarval();

1290      logIO("O","finished getting xcontent ...");
1291      xmlrpc_debugmsg( 'Getting xcontent'  );
1292  
1293      // getParam(4) should now be a flag for publish or draft

1294      $xstatus = $m->getParam(4);
1295      $xstatus = $xstatus->scalarval();
1296      $status = $xstatus ? 'published' : 'draft';
1297      logIO('I',"Publish: $xstatus -> Status: $status");
1298      logIO("O","finished getting xstatus ->". $xstatus);
1299  
1300      $contentstruct = xmlrpc_decode($xcontent); //this does not work properly.... need better decoding

1301      logIO("O","finished getting contentstruct ...");
1302  //    $content = format_to_post($contentstruct['description']);

1303      $post_title = $contentstruct['title'];
1304      $content = $contentstruct['description'];
1305      logIO("O","finished getting title ...".$post_title);
1306  
1307  
1308      // Categories:

1309      $cat_IDs = _mw_get_cat_IDs($contentstruct, $blog_ID);
1310  
1311      if( ! is_array($cat_IDs) )
1312      { // error:
1313          return $cat_IDs;
1314      }
1315  
1316  
1317      if( empty($contentstruct['dateCreated']) )
1318      {
1319          $postdate = date('Y-m-d H:i:s', (time() + $Settings->get('time_difference')));
1320          logIO("O","no contentstruct dateCreated, using now...".$postdate);
1321      }
1322      else
1323      {
1324          $postdate = $contentstruct['dateCreated'];
1325          logIO("O","finished getting contentstruct dateCreated...".$postdate);
1326      }
1327  
1328      // Check permission:

1329      $UserCache = & get_Cache( 'UserCache' );
1330      $current_User = & $UserCache->get_by_login( $username );
1331      logIO("O","currentuser ...". $current_User->ID);
1332  
1333      if( ! $current_User->check_perm( 'blog_post_statuses', 'published', false, $blog_ID ) )
1334      {
1335          logIO("O","user error 9 ...");
1336          return new xmlrpcresp(0, $xmlrpcerruser+2, 'Permission denied.'); // user error 2

1337      }
1338      logIO("O","finished checking permissions ...");
1339  
1340      // CHECK and FORMAT content - error occur after this line

1341      //$post_title = format_to_post($post_title, 0, 0);

1342      //logIO("O","finished converting post_title ...",$post_title);

1343  
1344      //$content = format_to_post($content, 0, 0);  // 25122004 tag - security !!!

1345      //logIO("O","finished converting content ...".$content); // error occurs before this line

1346  
1347      //    if( $errstring = $Messages->get_string( 'Cannot post, please correct these errors:', '' ) )

1348      //    {

1349      //        return new xmlrpcresp(0, $xmlrpcerruser+6, $errstring ); // user error 6

1350      //    }

1351      //logIO("O","finished checking if errors exists, ready to insert into DB ...");

1352  
1353      // INSERT NEW POST INTO DB:

1354      // Tor - comment this out to stop inserts into database

1355      $edited_Item = & new Item();
1356      $post_ID = $edited_Item->insert( $current_User->ID, $post_title, $content, $postdate, $cat_IDs[0], $cat_IDs, $status, $current_User->locale );
1357  
1358      if( $DB->error )
1359      {    // DB error
1360          logIO("O","user error 9 ...");
1361          return new xmlrpcresp(0, $xmlrpcerruser+9, 'DB error: '.$DB->last_error ); // user error 9

1362      }
1363  
1364      logIO( 'O', 'Handling notifications...' );
1365      // Execute or schedule notifications & pings:

1366      $edited_Item->handle_post_processing();
1367  
1368      return new xmlrpcresp(new xmlrpcval($post_ID));
1369  }
1370  
1371  
1372  // Movable Type API: {{{

1373  
1374  $mt_setPostCategories_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcArray));
1375  $mt_setPostCategories_doc = "Sets the categories for a post.";
1376  
1377  function mt_setPostCategories($m) {
1378      global $xmlrpcerruser,$Settings;
1379      global $DB, $Messages;
1380  
1381      $post_ID = $m->getParam(0);
1382      $post_ID = $post_ID->scalarval();
1383      $username = $m->getParam(1);
1384      $username = $username->scalarval();
1385      $password = $m->getParam(2);
1386      $password = $password->scalarval();
1387  
1388      if( ! user_pass_ok($username,$password) )
1389      {
1390          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1391                       'Wrong username/password combination '.$username.' / '.starify($password));
1392      }
1393  
1394  // ok - pick up new category from call

1395      $xcontent = $m->getParam(3); // This is now a array of structs

1396      $iSize = $xcontent->arraysize(); // The number of objects ie categories

1397      logIO("O","finished getting - iSize ...".$iSize); // number of categories entry has set

1398  
1399      logIO("O","finished getting contentstruct ...");
1400      $categories = array();
1401      if ($iSize > 0)
1402      {
1403          for ($i=0;$i<$iSize;$i++)
1404          {
1405              logIO("O","finished getting - i ...>".$i); // works!

1406              $struct = $xcontent->arraymem($i); // get a struct object from array

1407              $tempcat = $struct->structmem('categoryId');
1408              $tempcat = $tempcat->scalarval();
1409              $tempPrimary = $struct->structmem('isPrimary');// Start finding the primary category

1410              $tempPrimary = $tempPrimary->scalarval();
1411              if ($tempPrimary != 0)
1412              {
1413                  logIO("O","got primary category and there should only be one...".$tempcat);
1414                  $category = $tempcat;
1415              }
1416              logIO("O","finished getting - tempcat ...".$tempcat); // works!

1417              $categories[$i] = $tempcat;
1418              logIO("O","finished getting - categories ...".$categories[$i]);
1419          }
1420      }
1421  
1422      // UPDATE POST CATEGORIES IN DB:

1423      logIO("O","bpost_update - category ...".$category); // works!

1424      $ItemCache = & get_Cache( 'ItemCache' );
1425      if( ! ($edited_Item = & $ItemCache->get_by_ID( $post_ID ) ) )
1426      {
1427          return new xmlrpcresp(0, $xmlrpcerruser+7, "No such post (#$post_ID)."); // user error 7

1428      }
1429      $edited_Item->set( 'main_cat_ID', $category );
1430      $edited_Item->set( 'extra_cat_IDs', $categories );
1431  
1432      $edited_Item->dbupdate();
1433  
1434      return new xmlrpcresp(new xmlrpcval(1));
1435  }
1436  
1437  
1438  $mt_getPostCategories_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
1439  $mt_getPostCategories_doc = "Returns a list of all categories to which the post is assigned.";
1440  
1441  function mt_getPostCategories($m) {
1442      global $xmlrpcerruser;
1443      global $DB;
1444  
1445      $post_ID = $m->getParam(0);
1446      $post_ID = $post_ID->scalarval();
1447      logIO("O","mt_getPostCategories postID  ...".$post_ID);
1448      $username = $m->getParam(1);
1449      $username = $username->scalarval();
1450      $password = $m->getParam(2);
1451      $password = $password->scalarval();
1452      if( user_pass_ok($username,$password) )
1453      {
1454          // First get the primary category in postdata

1455          $postdata = get_postdata($post_ID);
1456          $dato = $postdata["Date"];
1457              logIO("O","mt_getPostCategories get_postdata argument postID  ...".$post_ID);
1458              logIO("O","mt_getPostCategories postdata argument date  ...".$dato);
1459          $Category = $postdata["Category"];// Primary category - nb also present in separate table so will not be used

1460              logIO("O","mt_getPostCategories postdata argument Category  ...".$Category);
1461          $categories = postcats_get_byID( $post_ID ); // Secondary categories

1462              logIO("O","mt_getPostCategories postcats_get_byID  ...".$categories);
1463          $iSize = count($categories); // The number of objects ie categories

1464          logIO("O","mt_getgategorylist  no of categories...".$iSize);// works

1465          $struct = array();
1466          for ($i=0;$i<$iSize;$i++)
1467          {
1468              logIO("O","mt_getPostCategories categories  ...".$categories[$i]);
1469  // In database cat_ID and cat_name from tablecategories

1470              $sql = "SELECT * FROM T_categories WHERE  cat_ID = $categories[$i] ";
1471              logIO("O","mt_getgategorylist  sql...".$sql);
1472              $rows = $DB->get_results( $sql );
1473              foreach( $rows as $row )
1474              {
1475                  $Categoryname =  $row->cat_name;
1476                  logIO("O","mt_getPostCategories Categoryname  ...".$Categoryname);
1477              }
1478              if( $postdata['Date'] != '' )
1479              {
1480                  logIO("O","mt_getPostCategories date ok  ...");
1481                  if ($i > 0) {
1482                  logIO("O","mt_getPostCategories found secondary  ...".$categories[$i]);
1483                      $isPrimary = "0";
1484                  }
1485              else
1486              {
1487                  logIO("O","mt_getPostCategories found primary  ...".$categories[$i]);
1488                  $isPrimary = "1";
1489              }
1490              $struct[$i] = new xmlrpcval(array("categoryId" => new xmlrpcval($categories[$i]),    // Look up name from ID separately
1491                                              "categoryName" => new xmlrpcval($Categoryname),
1492                                              "isPrimary" => new xmlrpcval($isPrimary)
1493                                              ),"struct");
1494          }
1495      }
1496      return new xmlrpcresp(new xmlrpcval($struct, "array") );
1497  //        else

1498  //        {

1499  //        return new xmlrpcresp(0, $xmlrpcerruser+7, // user error 7

1500  //                     "No such post #$post_ID");

1501  //        }

1502      }
1503      else
1504      {
1505          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1506                       'Wrong username/password combination '.$username.' / '.starify($password));
1507      }
1508  }
1509  
1510  
1511  $mt_getCategoryList_sig =  array(array($xmlrpcArray,$xmlrpcString,$xmlrpcString,$xmlrpcString));
1512  $mt_getCategoryList_doc = 'Get category list';
1513  /**

1514   * Provides mt.getCategoryList

1515   * @see http://www.sixapart.com/developers/xmlrpc/movable_type_api/mtgetcategorylist.html

1516   */
1517  function mt_getCategoryList($m) {
1518      logIO("O","mt_getCategoryList  start");
1519      return _b2_or_mt_get_categories('mt', $m);
1520  }
1521  
1522  // }}}

1523  
1524  
1525  $mweditpost_doc='Edits a post, blogger-api like, +title +category +postdate';
1526  $mweditpost_sig =  array(array($xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcStruct,$xmlrpcBoolean));
1527  /**

1528   * mw.EditPost (metaWeblog.editPost)

1529   *

1530   * mw API

1531   *

1532   * Tor - TODO

1533   *        - Sort out sql select with blog ID

1534   *        - screws up posts with multiple categories

1535   *          partly due to the fact that Movable Type calls to this API are different to Metaweblog API calls when handling categories.

1536   */
1537  
1538  function mweditpost($m)
1539  {
1540      global $xmlrpcerruser; // import user errcode value

1541      global $DB;
1542      global $Settings;
1543      global $Messages;
1544      global $xmlrpc_htmlchecking;
1545  
1546      logIO("O","start of mweditpost...");
1547      $post_ID = $m->getParam(0);
1548      $post_ID = $post_ID->scalarval();
1549      logIO("O","finished getting post_ID ...".$post_ID);
1550  
1551      // Username/Password

1552      $username = $m->getParam(1);
1553      $username = $username->scalarval();
1554      logIO("O","finished getting username ...");
1555      $password = $m->getParam(2);
1556      $password = $password->scalarval();
1557      logIO("O","finished getting password ...".$password);
1558      if( ! user_pass_ok($username,$password) )
1559      {
1560          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1561                       'Wrong username/password combination '.$username.' / '.starify($password));
1562      }
1563      logIO("O","finished checking password ...");
1564  
1565      // getParam(4) should now be a flag for publish or draft

1566      $xstatus = $m->getParam(4);
1567      $xstatus = $xstatus->scalarval();
1568      $status = $xstatus ? 'published' : 'draft';
1569      logIO('I',"Publish: $xstatus -> Status: $status");
1570      logIO("O","finished getting xstatus ->". $xstatus);
1571  
1572  
1573      // Get Item:

1574      $ItemCache = & get_Cache( 'ItemCache' );
1575      if( ! ($edited_Item = & $ItemCache->get_by_ID( $post_ID ) ) )
1576      {
1577          return new xmlrpcresp(0, $xmlrpcerruser+7, "No such post (#$post_ID)."); // user error 7

1578      }
1579  
1580      // Check permission:

1581      $UserCache = & get_Cache( 'UserCache' );
1582      $User = & $UserCache->get_by_login( $username );
1583      logIO('O','User ID ...'.$User->ID);
1584      if( ! $User->check_perm( 'blog_post_statuses', $status, false, $edited_Item->blog_ID ) )
1585      {
1586          return new xmlrpcresp(0, $xmlrpcerruser+2, 'Permission denied.'); // user error 2

1587      }
1588      logIO("O","finished checking permissions ...");
1589  
1590  
1591      $xcontent = $m->getParam(3);
1592  //    $xcontent = $xcontent->scalarval();

1593      logIO("O","finished getting xcontent ...");
1594      $contentstruct = xmlrpc_decode($xcontent); //this does not work properly.... need better decoding

1595      logIO("O","finished getting contentstruct ...");
1596  
1597  
1598      // Categories:

1599      $cat_IDs = _mw_get_cat_IDs($contentstruct, $blog_ID, true /* empty is ok */);
1600  
1601      if( ! is_array($cat_IDs) )
1602      { // error:
1603          return $cat_IDs;
1604      }
1605  
1606  
1607      $post_title = $contentstruct['title'];
1608      $content = $contentstruct['description'];
1609      logIO("O","finished getting title ...".$post_title);
1610  
1611      $postdate = $contentstruct['dateCreated'];
1612      logIO("O","finished getting contentstruct dateCreated...".$postdate);
1613  
1614  
1615      if( ! empty($xmlrpc_htmlchecking) )
1616      { // CHECK and FORMAT content
1617          $post_title = format_to_post($post_title, 0, 0);
1618      }
1619      logIO("O","finished converting post_title ...->".$post_title);
1620      if( ! empty($xmlrpc_htmlchecking) )
1621      {
1622          $content = format_to_post($content, 0, 0);  // 25122004 tag - security issue - need to sort !!!

1623      }
1624      logIO("O","finished converting content ...".$content);
1625      if( $errstring = $Messages->get_string( 'Cannot post, please correct these errors:', '' ) )
1626      {
1627          return new xmlrpcresp(0, $xmlrpcerruser+6, $errstring ); // user error 6

1628      }
1629      logIO("O","finished checking if errors exists, ready to insert into DB ...");
1630      xmlrpc_debugmsg( 'post_ID: '.$post_ID  );
1631  
1632      // UPDATE POST IN DB:

1633      $edited_Item->set( 'title', $post_title );
1634      $edited_Item->set( 'content', $content );
1635      $edited_Item->set( 'status', $status );
1636      if( ! empty($postdate) )
1637      {
1638          $edited_Item->set( 'datestart', $postdate );
1639      }
1640      if( ! empty($cat_IDs) )
1641      { // Update cats:
1642          $edited_Item->set('main_cat_ID', $cat_IDs[0]);
1643  
1644          if( count($cat_IDs) > 1 )
1645          { // Extra-Cats:
1646              $edited_Item->set('extra_cat_IDs', $cat_IDs);
1647          }
1648      }
1649      $edited_Item->dbupdate();
1650      if( $DB->error )
1651      {    // DB error
1652          return new xmlrpcresp(0, $xmlrpcerruser+9, 'DB error: '.$DB->last_error ); // user error 9

1653      }
1654  
1655  // Time to perform trackbacks NB NOT WORKING YET

1656  //

1657  // NB Requires a change to the _trackback library

1658  //

1659  // function trackbacks( $post_trackbacks, $content, $post_title, $post_ID )

1660  
1661  // first extract these from posting as post_trackbacks array, then rest is easy

1662  //     <member>

1663  //        <name>mt_tb_ping_urls</name>

1664  //    <value><array><data>

1665  //        <value><string>http://archive.scripting.com/2005/04/17</string></value>

1666  //    </data></array></value>

1667  //    </member>

1668  // First check that trackbacks are allowed - mt_allow_pings

1669      $trackback_ok = 0;
1670      $trackbacks = array();
1671      $trackback_ok = $contentstruct['mt_allow_pings'];
1672      logIO("O","Trackback OK  ...".$trackback_ok);
1673      if ($trackback_ok == 1)
1674      {
1675          $trackbacks = $contentstruct['mt_tb_ping_urls'];
1676          logIO("O","Trackback url 0  ...".$trackbacks[0]);
1677          $no_of_trackbacks = count($trackbacks);
1678          logIO("O","Number of Trackbacks  ...".$no_of_trackbacks);
1679          if ($no_of_trackbacks > 0)
1680          {
1681              logIO("O","Calling Trackbacks  ...");
1682              load_funcs('comments/_trackback.funcs.php');
1683               $result = trackbacks( $trackbacks, $content, $post_title, $post_ID );
1684              logIO("O","Returned from  Trackbacks  ...");
1685           }
1686  
1687      }
1688      return new xmlrpcresp(new xmlrpcval($post_ID));
1689  }
1690  
1691  
1692  
1693  $mwgetcats_sig =  array(array($xmlrpcArray,$xmlrpcString,$xmlrpcString,$xmlrpcString));
1694  $mwgetcats_doc = 'Get categories of a post, MetaWeblog API-style';
1695  /**

1696   * metaWeblog.getCategories

1697   * @see http://www.xmlrpc.com/metaWeblogApi#metawebloggetcategories

1698   */
1699  function mwgetcats( $m )
1700  {
1701      global $xmlrpcerruser, $DB;
1702  
1703      logIO('O','Start of mwgetcats');
1704      $blogid = $m->getParam(0);
1705      $blogid = $blogid->scalarval();
1706      $username = $m->getParam(1);
1707      $username = $username->scalarval();
1708      $password = $m->getParam(2);
1709      $password = $password->scalarval();
1710      logIO('O','Got params 0, 1 , 2');
1711      if( ! user_pass_ok($username,$password) )
1712      {
1713          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1714                       'Wrong username/password combination '.$username.' / '.starify($password));
1715      }
1716      $sql = "SELECT cat_ID, cat_name
1717                      FROM T_categories ";
1718  
1719      $BlogCache = & get_Cache('BlogCache');
1720      $current_Blog = $BlogCache->get_by_ID( $blog );
1721      $aggregate_coll_IDs = $current_Blog->get_setting('aggregate_coll_IDs');
1722      if( empty( $aggregate_coll_IDs ) )
1723      {    // We only want posts from the current blog:
1724          $sql .= 'WHERE cat_blog_ID ='.$current_Blog->ID;
1725      }
1726      else
1727      {    // We are aggregating posts from several blogs:
1728          $sql .= 'WHERE cat_blog_ID IN ('.$aggregate_coll_IDs.')';
1729      }
1730  
1731      $sql .= " ORDER BY cat_name ASC";
1732      $rows = $DB->get_results( $sql );
1733      if( $DB->error )
1734      {    // DB error
1735          return new xmlrpcresp(0, $xmlrpcerruser+9, 'DB error: '.$DB->last_error ); // user error 9

1736      }
1737      xmlrpc_debugmsg( 'Categories:'.count($rows) );
1738  
1739      $ChapterCache = & get_Cache('ChapterCache');
1740      $data = array();
1741      foreach( $rows as $row )
1742      {
1743          $Chapter = & $ChapterCache->get_by_ID($row->cat_ID);
1744          if( ! $Chapter )
1745          {
1746              continue;
1747          }
1748          $data[] = new xmlrpcval( array(
1749                  'categoryId' => new xmlrpcval( $row->cat_ID ), // not in RFC (http://www.xmlrpc.com/metaWeblogApi)
1750                  'description' => new xmlrpcval( $row->cat_name ), // not in RFC (http://www.xmlrpc.com/metaWeblogApi)
1751                  'categoryName' => new xmlrpcval( $row->cat_name ),
1752                  'htmlUrl' => new xmlrpcval( $Chapter->get_permanent_url() ),
1753                  'rssUrl' => new xmlrpcval( url_add_param($Chapter->get_permanent_url(), 'tempskin=_rss2') )
1754              //    mb_convert_encoding( $row->cat_name, "utf-8", "iso-8859-1")  )

1755              ),"struct");
1756      }
1757      return new xmlrpcresp( new xmlrpcval($data, "array") );
1758  }
1759  
1760  
1761  
1762  
1763  
1764  $metawebloggetrecentposts_doc = 'fetches X most recent posts, blogger-api like';
1765  $metawebloggetrecentposts_sig =  array(array($xmlrpcArray,$xmlrpcString,$xmlrpcString,$xmlrpcString,$xmlrpcInt));
1766  
1767  function metawebloggetrecentposts( $m )
1768  {
1769      global $xmlrpcerruser, $DB;
1770      global $blog;
1771  
1772      $blog_ID = $m->getParam(0);
1773          logIO("O","In metawebloggetrecentposts, current blog_id is ...". $blog_ID);
1774      $blog_ID = $blog_ID->scalarval();
1775              logIO("O","In metawebloggetrecentposts, current blog_id is ...". $blog_ID);
1776      $username = $m->getParam(1);
1777          logIO("O","In metawebloggetrecentposts, current username is ...". $username);
1778      $username = $username->scalarval();
1779              logIO("O","In metawebloggetrecentposts, current username is ...". $username);
1780      $password = $m->getParam(2);
1781      $password = $password->scalarval();
1782      $numposts = $m->getParam(3);
1783              logIO("O","In metawebloggetrecentposts, current numposts is ...". $numposts);
1784      $numposts = $numposts->scalarval();
1785                  logIO("O","In metawebloggetrecentposts, current numposts is ...". $numposts);
1786  
1787      if( ! user_pass_ok($username, $password) )
1788      {
1789          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1790                       'Wrong username/password combination '.$username.' / '.starify($password));
1791      }
1792      logIO("O","In metawebloggetrecentposts, user and pass ok...");
1793      $UserCache = & get_Cache( 'UserCache' );
1794      $current_User = & $UserCache->get_by_login( $username );
1795      logIO( 'O', 'In metawebloggetrecentposts, current user is ...'.$current_User->ID );
1796      // Check permission:

1797      if( ! $current_User->check_perm( 'blog_ismember', 1, false, $blog_ID ) )
1798      {
1799          return new xmlrpcresp(0, $xmlrpcerruser+2, 'Permission denied.' ); // user error 2

1800      }
1801      logIO("O","In metawebloggetrecentposts, permissions ok...");
1802      logIO("O","In metawebloggetrecentposts, current blog is ...". $blog_ID);
1803  
1804      $BlogCache = & get_Cache( 'BlogCache' );
1805      $Blog = & $BlogCache->get_by_ID( $blog_ID );
1806  
1807      // Get the posts to display:

1808      $MainList = & new ItemList2( $Blog, NULL, NULL, $numposts );
1809  
1810      $MainList->set_filters( array(
1811              'visibility_array' => array( 'published', 'protected', 'private', 'draft', 'deprecated', 'redirected' ),
1812              'order' => 'DESC',
1813              'unit' => 'posts',
1814          ) );
1815  
1816      // Run the query:

1817      $MainList->query();
1818  
1819      xmlrpc_debugmsg( 'Items:'.$MainList->result_num_rows );
1820  
1821      $data = array();
1822      while( $Item = & $MainList->get_item() )
1823      {
1824          xmlrpc_debugmsg( 'Item:'.$Item->title.
1825                                              ' - Issued: '.$Item->issue_date.
1826                                              ' - Modified: '.$Item->mod_date );
1827          $post_date = mysql2date("U", $Item->issue_date);
1828          $post_date = gmdate("Ymd", $post_date)."T".gmdate("H:i:s", $post_date);
1829          $content = $Item->content;
1830          $content = str_replace("\n",'',$content); // Tor - kludge to fix bug in xmlrpc libraries

1831          // Load Item's creator User:

1832          $Item->get_creator_User();
1833          $authorname = $Item->creator_User->get('preferredname');
1834          // need a loop here to extract all categoy names

1835          // $extra_cat_IDs is the variable for the rest of the IDs

1836          $hope_cat_name = get_the_category_by_ID($Item->main_cat_ID);
1837          $test = $Item->extra_cat_IDs[0];
1838          xmlrpc_debugmsg( 'postcats:'.$hope_cat_name["cat_name"]);
1839          xmlrpc_debugmsg( 'test:'.$test);
1840          $data[] = new xmlrpcval(array(
1841                                      "dateCreated" => new xmlrpcval($post_date,"dateTime.iso8601"),
1842                                      "userid" => new xmlrpcval($Item->creator_user_ID),
1843                                      "postid" => new xmlrpcval($Item->ID),
1844                  "categories" => new xmlrpcval(array(new xmlrpcval($hope_cat_name["cat_name"])),'array'),
1845                  "title" => new xmlrpcval($Item->title),
1846                  "description" => new xmlrpcval($content),
1847                  "link" => new xmlrpcval($Item->url),
1848                  "permalink" => new xmlrpcval($Item->urltitle),
1849                  "mt_excerpt" => new xmlrpcval($content),
1850                  "mt_allow_comments" => new xmlrpcval('1'),
1851                  "mt_allow_pings" => new xmlrpcval('1'),
1852                  "mt_text_more" => new xmlrpcval('')
1853                                      ),"struct");
1854      }
1855      $resp = new xmlrpcval($data, "array");
1856      return new xmlrpcresp($resp);
1857  }
1858  
1859  
1860  
1861  
1862  
1863  
1864  $mwgetpost_doc = 'fetches a post, blogger-api like';
1865  $mwgetpost_sig = array(array($xmlrpcString, $xmlrpcString, $xmlrpcString, $xmlrpcString));
1866  /**

1867   * metaweblog.getPost retieves a given post.

1868   *

1869   * This API call is not documented on

1870   * {@link http://www.blogger.com/developers/api/1_docs/}

1871   *

1872   * @param xmlrpcmsg XML-RPC Message

1873   *                    0 appkey (string): Unique identifier/passcode of the application sending the post.

1874   *                        (See access info {@link http://www.blogger.com/developers/api/1_docs/#access} .)

1875   *                    1 postid (string): Unique identifier of the post to be deleted.

1876   *                    2 username (string): Login for a Blogger user who has permission to edit the given

1877   *                        post (either the user who originally created it or an admin of the blog).

1878   *                    3 password (string): Password for said username.

1879   * @return xmlrpcresp XML-RPC Response

1880   */
1881  
1882  function mwgetpost($m)
1883  {
1884  
1885      global $xmlrpcerruser;
1886  
1887  
1888  
1889      $post_ID = $m->getParam(0);
1890      $post_ID = $post_ID->scalarval();
1891      $username = $m->getParam(1);
1892      $username = $username->scalarval();
1893      $password = $m->getParam(2);
1894      $password = $password->scalarval();
1895      if( user_pass_ok($username,$password) )
1896      {
1897          $postdata = get_postdata($post_ID);
1898          if( $postdata['Date'] != '' )
1899          {
1900              $post_date = mysql2date("U", $postdata["Date"]);
1901              $post_date = gmdate("Ymd", $post_date)."T".gmdate("H:i:s", $post_date);
1902              $content = $postdata["Content"];
1903                              // Kludge to fix library problem str_replace(#10,'',$content)

1904          $content = str_replace("\n",'',$content); // Tor - kludge to fix bug in xmlrpc libraries

1905              $struct = new xmlrpcval(array("link" => new xmlrpcval(''),
1906                                              "title" => new xmlrpcval($postdata["Title"]),
1907                                              "description" => new xmlrpcval($content),
1908                                              "dateCreated" => new xmlrpcval($post_date,"dateTime.iso8601"),
1909                                              "userid" => new xmlrpcval(""),
1910                                              "postid" => new xmlrpcval($post_ID),
1911                                              "content" => new xmlrpcval($content),
1912                                              "permalink" => new xmlrpcval(""),
1913                                              "categories" => new xmlrpcval($postdata["Category"]),
1914                                              "mt_excerpt" => new xmlrpcval($content),
1915                                              "mt_allow_comments" => new xmlrpcval("",'int'),
1916                                              "mt_allow_pings" => new xmlrpcval("",'int'),
1917                                              "mt_text_more" => new xmlrpcval("")
1918                                              ),"struct");
1919              $resp = $struct;
1920              return new xmlrpcresp($resp);
1921          }
1922          else
1923          {
1924          return new xmlrpcresp(0, $xmlrpcerruser+7, // user error 7
1925                       "No such post #$post_ID");
1926          }
1927      }
1928      else
1929      {
1930          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1931                       'Wrong username/password combination '.$username.' / '.starify($password));
1932      }
1933  }
1934  
1935  
1936  /**

1937   * Helper for {@link b2getcategories()} and {@link mt_getPostCategories()}, because they differ

1938   * only in the "categoryId" case ("categoryId" (b2) vs "categoryID" (MT))

1939   *

1940   * @param string Type, either "b2" or "mt"

1941   * @param xmlrpcmsg XML-RPC Message

1942   *                    0 blogid (string): Unique identifier of the blog to query

1943   *                    1 username (string): Login for a Blogger user who is member of the blog.

1944   *                    2 password (string): Password for said username.

1945   * @return xmlrpcresp XML-RPC Response

1946   */
1947  function _b2_or_mt_get_categories( $type, $m )
1948  {
1949      global $xmlrpcerruser, $DB;
1950  
1951      $blogid = $m->getParam(0);
1952      $blogid = $blogid->scalarval();
1953  
1954      $username = $m->getParam(1);
1955      $username = $username->scalarval();
1956  
1957      $password = $m->getParam(2);
1958      $password = $password->scalarval();
1959  
1960      if( ! user_pass_ok($username,$password) )
1961      {
1962          return new xmlrpcresp(0, $xmlrpcerruser+1, // user error 1
1963                       'Wrong username/password combination '.$username.' / '.starify($password));
1964      }
1965  
1966      $sql = 'SELECT *
1967                      FROM T_categories ';
1968  
1969      $BlogCache = & get_Cache('BlogCache');
1970      $current_Blog = $BlogCache->get_by_ID( $blog );
1971      $aggregate_coll_IDs = $current_Blog->get_setting('aggregate_coll_IDs');
1972      if( empty( $aggregate_coll_IDs ) )
1973      {    // We only want posts from the current blog:
1974          $sql .= 'WHERE cat_blog_ID ='.$current_Blog->ID;
1975      }
1976      else
1977      {    // We are aggregating posts from several blogs:
1978          $sql .= 'WHERE cat_blog_ID IN ('.$aggregate_coll_IDs.')';
1979      }
1980  
1981      $sql .= " ORDER BY cat_name ASC";
1982  
1983      $rows = $DB->get_results( $sql );
1984      if( $DB->error )
1985      { // DB error
1986          return new xmlrpcresp(0, $xmlrpcerruser+9, 'DB error: '.$DB->last_error ); // user error 9

1987      }
1988  
1989      xmlrpc_debugmsg( 'Categories:'.count($rows) );
1990  
1991      $categoryIdName = ( $type == 'b2' ? 'categoryID' : 'categoryId' );
1992      $data = array();
1993      foreach( $rows as $row )
1994      {
1995          $data[] = new xmlrpcval( array(
1996                  $categoryIdName => new xmlrpcval($row->cat_ID),
1997                  'categoryName' => new xmlrpcval( $row->cat_name )
1998              //    mb_convert_encoding( $row->cat_name, "utf-8", "iso-8859-1")  )

1999              ), 'struct' );
2000      }
2001  
2002      return new xmlrpcresp( new xmlrpcval($data, "array") );
2003  }
2004  
2005  
2006  /**

2007   *

2008   * @param array struct

2009   * @param integer blog ID

2010   * @param boolean Return empty array (instead of error), if no cats given in struct?

2011   * @return array|xmlrpcresp A list of category IDs or xmlrpcresp in case of error.

2012   */
2013  function _mw_get_cat_IDs($contentstruct, $blog_ID, $empty_struct_ok = false)
2014  {
2015      global $DB, $xmlrpcerruser;
2016  
2017      if( isset($contentstruct['categories']) )
2018      {
2019          $categories = $contentstruct['categories'];
2020      }
2021      else
2022      {
2023          $categories = array();
2024      }
2025      logIO("O","finished getting contentstruct categories...".implode( ', ', $categories ) );
2026  
2027      if( $empty_struct_ok && empty($categories) )
2028      {
2029          return $categories;
2030      }
2031  
2032      xmlrpc_debugmsg( 'Categories: '.implode( ', ', $categories ) );
2033  
2034      // for cross-blog-entries, the cat_blog_ID WHERE clause should be removed (but cats are given by name!)

2035      if( ! empty($categories) )
2036      {
2037          $sql = "
2038              SELECT cat_ID FROM T_categories
2039               WHERE cat_blog_ID = $blog_ID
2040                   AND cat_name IN ( ";
2041          foreach( $categories as $l_cat )
2042          {
2043              $sql .= $DB->quote($l_cat).', ';
2044          }
2045          if( ! empty($categories) )
2046          {
2047              $sql = substr($sql, 0, -2); // remove ', '

2048          }
2049          $sql .= ' )';
2050          logIO("O","sql for finding IDs ...".$sql);
2051  
2052          $cat_IDs = $DB->get_col( $sql );
2053          if( $DB->error )
2054          {    // DB error
2055              logIO("O","user error finding categories info ...");
2056          }
2057      }
2058      else
2059      {
2060          $cat_IDs = array();
2061      }
2062  
2063      if( ! empty($cat_IDs) )
2064      { // categories requested to be set:
2065  
2066          // Check if category exists

2067          if( get_the_category_by_ID( $cat_IDs[0], false ) === false )
2068          { // Main cat does not exist:
2069              logIO("O","usererror 5 ...");
2070              return new xmlrpcresp(0, $xmlrpcerruser+5, 'Requested category does not exist.'); // user error 5

2071          }
2072          logIO("O","finished checking if main category exists ...".$cat_IDs[0]);
2073      }
2074      else
2075      { // No category given/valid - use the first for the blog:
2076          logIO("O","No category for post given ...");
2077  
2078          $first_cat = $DB->get_var( '
2079              SELECT cat_ID
2080                FROM T_categories
2081               WHERE cat_blog_ID = '.$blog_ID.'
2082               ORDER BY cat_name
2083               LIMIT 1' );
2084          if( empty($first_cat) )
2085          {
2086              logIO("O", 'No categories for this blog...');
2087              return new xmlrpcresp(0, $xmlrpcerruser+5, 'No categories for this blog.'); // user error 5

2088          }
2089          else
2090          {
2091              $cat_IDs = array($first_cat);
2092          }
2093      }
2094  
2095      return $cat_IDs;
2096  }
2097  
2098  
2099  
2100  /**** SERVER FUNCTIONS ARRAY ****/

2101  // dh> TODO: Plugin hook here, so that Plugins can provide own callbacks?!

2102  // fp> The current implementation of this file is not optimal (file is way too large)

2103  // fp> xmlrpc.php should actually only be a switcher and it should load the function to execute once it has been identified

2104  // fp> maybe it would make sense to register xmlrpc apis/functions in a DB table

2105  // fp> it would probably make sense to have *all* xmlrpc methods implemented as plugins (maybe 1 plugin per API; it should be possible to add a single func to an API with an additional plugin)

2106  // dh> NOTE: some tools may use different API entry points, e.g. for extended methods.. (But I'm not sure..)

2107  // fp> from a security standpoint it would make a lot of sense to disable any rpc that is not needed

2108  
2109  load_funcs('_ext/xmlrpc/_xmlrpcs.php'); // This will add generic remote calls

2110  
2111  $s = new xmlrpc_server(
2112      array(
2113          "metaWeblog.newMediaObject" =>
2114              array(
2115                  "function" => "mwnewMediaObject",
2116                  "signature" => $mwnewMediaObject_sig,
2117                  "docstring" => $mwnewMediaObject_doc),
2118  
2119          "metaWeblog.newPost" =>
2120              array(
2121                  "function" => "mwnewpost",
2122                  "signature" => $mwnewpost_sig,
2123                  "docstring" => $mwnewpost_doc),
2124  
2125          "metaWeblog.editPost" =>
2126              array(
2127                  "function" => "mweditpost",
2128                  "signature" => $mweditpost_sig,
2129                  "docstring" => $mweditpost_doc),
2130  
2131          "metaWeblog.getPost" =>
2132              array(
2133                  "function" => "mwgetpost",
2134                  "signature" => $mwgetpost_sig,
2135                  "docstring" => $mwgetpost_doc),
2136  
2137          "metaWeblog.getCategories" =>
2138              array(
2139                  "function" => "mwgetcats",
2140                  "signature" => $mwgetcats_sig,
2141                  "docstring" => $mwgetcats_doc),
2142  
2143          "metaWeblog.getRecentPosts" =>
2144              array(
2145                  "function" => "metawebloggetrecentposts",
2146                  "signature" => $metawebloggetrecentposts_sig,
2147                  "docstring" => $metawebloggetrecentposts_doc),
2148  
2149          "b2.newPost" =>
2150              array(
2151                  "function" => "b2newpost",
2152                  "signature" => $b2newpost_sig,
2153                  "docstring" => $b2newpost_doc),
2154  
2155          "b2.getCategories" =>
2156              array(
2157                  "function" => "b2getcategories",
2158                  "signature" => $b2getcategories_sig,
2159                  "docstring" => $b2getcategories_doc),
2160  
2161          "b2.getPostURL" =>
2162              array(
2163                  "function" => "b2_getPostURL",
2164                  "signature" => $b2_getPostURL_sig,
2165                  "docstring" => $b2_getPostURL_doc),
2166  
2167          "blogger.newPost" =>
2168              array(
2169                  "function" => "bloggernewpost",
2170                  "signature" => $bloggernewpost_sig,
2171                  "docstring" => $bloggernewpost_doc),
2172  
2173          "blogger.editPost" =>
2174              array(
2175                  "function" => "bloggereditpost",
2176                  "signature" => $bloggereditpost_sig,
2177                  "docstring" => $bloggereditpost_doc),
2178  
2179          "blogger.deletePost" =>
2180              array(
2181                  "function" => "bloggerdeletepost",
2182                  "signature" => $bloggerdeletepost_sig,
2183                  "docstring" => $bloggerdeletepost_doc),
2184  
2185          "blogger.getUsersBlogs" =>
2186              array(
2187                  "function" => "bloggergetusersblogs",
2188                  "signature" => $bloggergetusersblogs_sig,
2189                  "docstring" => $bloggergetusersblogs_doc),
2190  
2191          "blogger.getUserInfo" =>
2192              array(
2193                  "function" => "bloggergetuserinfo",
2194                  "signature" => $bloggergetuserinfo_sig,
2195                  "docstring" => $bloggergetuserinfo_doc),
2196  
2197          "blogger.getPost" =>
2198              array(
2199                  "function" => "bloggergetpost",
2200                  "signature" => $bloggergetpost_sig,
2201                  "docstring" => $bloggergetpost_doc),
2202  
2203          "blogger.getRecentPosts" =>
2204              array(
2205                  "function" => "bloggergetrecentposts",
2206                  "signature" => $bloggergetrecentposts_sig,
2207                  "docstring" => $bloggergetrecentposts_doc),
2208  
2209          "blogger.getTemplate" =>
2210              array(
2211                  "function" => "bloggergettemplate",
2212                  "signature" => $bloggergettemplate_sig,
2213                  "docstring" => $bloggergettemplate_doc),
2214  
2215          "blogger.setTemplate" =>
2216              array(
2217                  "function" => "bloggersettemplate",
2218                  "signature" => $bloggersettemplate_sig,
2219                  "docstring" => $bloggersettemplate_doc),
2220  
2221          "mt.getPostCategories" =>
2222              array(
2223                  "function" => "mt_getPostCategories",
2224                  "signature" => $mt_getPostCategories_sig,
2225                  "docstring" => $mt_getPostCategories_doc),
2226  
2227          "mt.getCategoryList" =>
2228              array(
2229                  "function" => "mt_getCategoryList",
2230                  "signature" => $mt_getCategoryList_sig,
2231                  "docstring" => $mt_getCategoryList_doc),
2232  
2233          "mt.setPostCategories" =>
2234              array(
2235                  "function" => "mt_setPostCategories",
2236                  "signature" => $mt_setPostCategories_sig,
2237                  "docstring" => $mt_setPostCategories_doc),
2238      )
2239  );
2240  
2241  /*

2242   * $Log: xmlrpc.php,v $

2243   * Revision 1.139  2007/06/27 02:23:32  fplanque

2244   * new default template for skins named index.main.php

2245   *

2246   * Revision 1.138  2007/06/25 11:02:42  fplanque

2247   * MODULES (refactored MVC)

2248   *

2249   * Revision 1.137  2007/05/21 19:40:15  blueyed

2250   * Fixed usage of $HTTP_RAW_POST_DATA global by using php://input stream, if $HTTP_RAW_POST_DATA is not set.

2251   *

2252   * Revision 1.136  2007/05/09 01:00:25  fplanque

2253   * optimized querying for blog lists

2254   *

2255   * Revision 1.135  2007/05/08 18:50:47  fplanque

2256   * minor fixes

2257   *

2258   * Revision 1.134  2007/04/26 00:11:14  fplanque

2259   * (c) 2007

2260   *

2261   * Revision 1.133  2007/03/20 07:39:08  fplanque

2262   * filemanager fixes, including the chmod octal stuff

2263   *

2264   * Revision 1.132  2007/03/11 23:57:07  fplanque

2265   * item editing: allow setting to 'redirected' status

2266   *

2267   * Revision 1.131  2006/12/23 23:37:35  fplanque

2268   * refactoring / Blog::get_default_cat_ID()

2269   *

2270   * Revision 1.130  2006/12/17 23:42:40  fplanque

2271   * Removed special behavior of blog #1. Any blog can now aggregate any other combination of blogs.

2272   * Look into Advanced Settings for the aggregating blog.

2273   * There may be side effects and new bugs created by this. Please report them :]

2274   *

2275   * Revision 1.129  2006/12/12 02:53:57  fplanque

2276   * Activated new item/comments controllers + new editing navigation

2277   * Some things are unfinished yet. Other things may need more testing.

2278   *

2279   * Revision 1.128  2006/12/06 17:49:11  blueyed

2280   * Moved strip_all_but_one_link() to obsolete2.php; doc (pingback removed)

2281   *

2282   * Revision 1.127  2006/12/05 07:23:22  blueyed

2283   * Fixed categories handling also for blogger.editPost; doc

2284   *

2285   * Revision 1.126  2006/12/05 06:31:41  blueyed

2286   * Nuked $default_category from XMLRPC

2287   *

2288   * Revision 1.125  2006/12/05 06:22:25  blueyed

2289   * Fixed blogger.newPost to accept a list of categories, as given by w.bloggar

2290   *

2291   * Revision 1.124  2006/12/03 18:22:58  blueyed

2292   * Nuked deprecated fileupload globals

2293   *

2294   * Revision 1.122  2006/12/03 01:24:38  blueyed

2295   * "htmlUrl" and "rssUrl" for metaWeblog.getCategories

2296   *

2297   * Revision 1.121  2006/12/02 19:51:08  blueyed

2298   * "categoryId" case fixes; see http://forums.b2evolution.net/viewtopic.php?p=47650#47650

2299   *

2300   * Revision 1.120  2006/11/16 19:14:10  fplanque

2301   * minor

2302   *

2303   * Revision 1.119  2006/11/13 20:49:53  fplanque

2304   * doc/cleanup :/

2305   *

2306   * Revision 1.118  2006/11/05 20:13:57  fplanque

2307   * minor

2308   *

2309   * Revision 1.117  2006/10/10 19:23:51  blueyed

2310   * Use set()/dbupdate() instead of update() in bloggereditpost()

2311   *

2312   * Revision 1.116  2006/10/01 20:08:39  blueyed

2313   * Removed DEBUG_XMLRPC_LOGGING constant again. It gave a notice when using the xmlrpcclient e.g. for sending pings and is not as flexible as a global.

2314   *

2315   * Revision 1.115  2006/09/22 21:27:53  blueyed

2316   * Minor fixes for RSD, formatting, whitespace.

2317   *

2318   * Revision 1.114  2006/09/22 19:11:20  wendall911

2319   * Added rsd support, restored 0.9.x functionality

2320   *

2321   * Revision 1.113  2006/09/06 21:39:23  fplanque

2322   * ItemList2 fixes

2323   *

2324   * Revision 1.112  2006/09/06 20:45:34  fplanque

2325   * ItemList2 fixes

2326   *

2327   * Revision 1.111  2006/09/06 18:34:07  fplanque

2328   * Finally killed the old stinkin' ItemList(1) class which is deprecated by ItemList2

2329   *

2330   * Revision 1.110  2006/08/29 00:26:12  fplanque

2331   * Massive changes rolling in ItemList2.

2332   * This is somehow the meat of version 2.0.

2333   * This branch has gone officially unstable at this point! :>

2334   *

2335   * Revision 1.109  2006/08/21 16:07:45  fplanque

2336   * refactoring

2337   *

2338   * Revision 1.108  2006/08/21 00:03:13  fplanque

2339   * obsoleted some dirty old thing

2340   *

2341   * Revision 1.107  2006/08/19 07:56:32  fplanque

2342   * Moved a lot of stuff out of the automatic instanciation in _main.inc

2343   *

2344   * Revision 1.106  2006/08/19 02:15:09  fplanque

2345   * Half kille dthe pingbacks

2346   * Still supported in DB in case someone wants to write a plugin.

2347   *

2348   * Revision 1.105  2006/08/01 23:32:45  blueyed

2349   * Moved $xmlrpc_logging into /conf/_advanced.php (and renamed it to $debug_xmlrpc_logging), so it can get overridden easily.

2350   *

2351   * Revision 1.104  2006/08/01 22:56:38  blueyed

2352   * Fixed "perm denied"

2353   *

2354   * Revision 1.103  2006/08/01 22:53:31  blueyed

2355   * Fix

2356   *

2357   * Revision 1.102  2006/08/01 21:53:02  blueyed

2358   * Fixes

2359   *

2360   * Revision 1.101  2006/08/01 19:23:55  blueyed

2361   * fixes

2362   *

2363   * Revision 1.100  2006/08/01 18:43:27  blueyed

2364   * Removed last deprecated $table.. occurences.

2365   *

2366   * Revision 1.99  2006/08/01 18:24:10  blueyed

2367   * Fixes:

2368   *  - metaWeblog.editPost:

2369   *    - respect publish/status param

2370   *    - check perms

2371   *    - only update relevant parts of item

2372   *  - mt.setPostCategories: set only categories (keep status etc)

2373   * Features:

2374   *  - support categories for metaWeblog.editPost/newPost

2375   * Code cleanup!

2376   * Completely untested.. :/

2377   *

2378   * Revision 1.97  2006/07/24 00:05:46  fplanque

2379   * cleaned up skins

2380   *

2381   * Revision 1.96  2006/07/06 19:56:31  fplanque

2382   * no message

2383   *

2384   * Revision 1.95  2006/07/02 21:53:31  blueyed

2385   * time difference as seconds instead of hours; validate user#1 on upgrade; bumped new_db_version to 9300.

2386   *

2387   * Revision 1.94  2006/05/30 20:32:57  blueyed

2388   * Lazy-instantiate "expensive" properties of Comment and Item.

2389   *

2390   * Revision 1.93  2006/03/24 01:04:33  blueyed

2391   * Fix for mt.getCategoryList? At least E_NOTICE fixed.

2392   *

2393   * Revision 1.91  2006/03/18 19:17:54  blueyed

2394   * Removed remaining use of $img_url

2395   *

2396   * Revision 1.90  2006/03/12 23:09:31  fplanque

2397   * doc cleanup

2398   *

2399   * Revision 1.89  2006/03/09 22:30:02  fplanque

2400   * cleaned up permanent urls

2401   *

2402   * Revision 1.88  2006/03/09 20:40:41  fplanque

2403   * cleanup

2404   *

2405   * Revision 1.87  2006/02/23 21:12:54  fplanque

2406   * File reorganization to MVC (Model View Controller) architecture.

2407   * See index.hml files in folders.

2408   * (Sorry for all the remaining bugs induced by the reorg... :/)

2409   *

2410   * Revision 1.86  2006/01/06 16:42:41  fplanque

2411   * bugfix

2412   *

2413   * Revision 1.80  2005/10/29 19:46:45  tor_gisvold

2414   * Bug fix for all blogger API routines - all of these errored due to lack of global cache definition

2415   * I also hope that I have fixed the pesky double line spacing done by my CVS frontend - if not I apologise and will fix.

2416   *

2417   * Revision 1.79  2005/10/23 18:14:24  tor_gisvold

2418   * Metaweblog API and Movable Type API first cut for new version of b2evolution

2419   * Tor 23102005

2420   */
2421  ?>


Généré le : Thu Nov 29 23:58:50 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics