Wordpress XML-RPC PHP Client
  • Namespace
  • Class

Namespaces

  • HieuLe
    • WordpressXmlrpcClient
      • Exception

Classes

  • HieuLe\WordpressXmlrpcClient\WordpressClient

Exceptions

  • HieuLe\WordpressXmlrpcClient\Exception\NetworkException
  • HieuLe\WordpressXmlrpcClient\Exception\XmlrpcException
   1 <?php
   2 
   3 namespace HieuLe\WordpressXmlrpcClient;
   4 
   5 /**
   6  * A XML-RPC client that implement the {@link http://codex.wordpress.org/XML-RPC_WordPress_API Wordpress API}.
   7  *
   8  * @version 2.5.0
   9  *
  10  * @author  Hieu Le <http://www.hieule.info>
  11  *
  12  * @license http://opensource.org/licenses/MIT MIT
  13  */
  14 class WordpressClient
  15 {
  16 
  17     private $username;
  18     private $password;
  19     private $endPoint;
  20     private $request;
  21     private $responseHeader = array();
  22     private $error;
  23     private $proxyConfig = false;
  24     private $authConfig = false;
  25     private $userAgent;
  26 
  27     /**
  28      * Event custom callbacks
  29      */
  30     private $_callbacks = array();
  31 
  32     /**
  33      * Create a new client
  34      *
  35      * @param string                 $xmlrpcEndPoint The wordpress XML-RPC endpoint (optional)
  36      * @param string                 $username       The client's username (optional)
  37      * @param string                 $password       The client's password (optional)
  38      * @param \Illuminate\Log\Writer $logger         deprecated. This variable will not be used since 2.4.0
  39      */
  40     public function __construct($xmlrpcEndPoint = null, $username = null, $password = null, $logger = null)
  41     {
  42         $this->setCredentials($xmlrpcEndPoint, $username, $password);
  43         $this->userAgent = $this->getDefaultUserAgent();
  44     }
  45 
  46     /**
  47      * Add a callback for `error` event
  48      *
  49      * @param Closure $callback
  50      *
  51      * @since 2.4.0
  52      */
  53     function onError($callback)
  54     {
  55         $this->_callbacks['error'][] = $callback;
  56     }
  57 
  58     /**
  59      * Add a callback for `sending` event
  60      *
  61      * @param Closure $callback
  62      *
  63      * @since 2.4.0
  64      */
  65     function onSending($callback)
  66     {
  67         $this->_callbacks['sending'][] = $callback;
  68     }
  69 
  70     /**
  71      * Set the endpoint, username and password for next requests
  72      *
  73      * @param string $xmlrpcEndPoint The wordpress XML-RPC endpoint
  74      * @param string $username       The client's username
  75      * @param string $password       The client's password
  76      *
  77      * @since 2.4.0
  78      */
  79     function setCredentials($xmlrpcEndPoint, $username, $password)
  80     {
  81         // prepend http protocol to the end point if needed
  82         $scheme = parse_url($xmlrpcEndPoint, PHP_URL_SCHEME);
  83         if (!$scheme) {
  84             $xmlrpcEndPoint = "http://{$xmlrpcEndPoint}";
  85         }
  86 
  87         // swith to https when working with wordpress.com blogs
  88         $host = parse_url($xmlrpcEndPoint, PHP_URL_HOST);
  89         if (substr($host, -14) == '.wordpress.com') {
  90             $xmlrpcEndPoint = preg_replace('|http://|', 'https://', $xmlrpcEndPoint, 1);
  91         }
  92 
  93         // save information
  94         $this->endPoint = $xmlrpcEndPoint;
  95         $this->username = $username;
  96         $this->password = $password;
  97     }
  98 
  99     /**
 100      * Get the current endpoint URL
 101      *
 102      * @return string
 103      *
 104      * @since 2.4.2
 105      */
 106     function getEndPoint()
 107     {
 108         return $this->endPoint;
 109     }
 110 
 111     /**
 112      * Get library default user agent
 113      *
 114      * @return string
 115      *
 116      * @since 2.4.0
 117      */
 118     function getDefaultUserAgent()
 119     {
 120         $phpVersion  = phpversion();
 121         $curlVersion = curl_version();
 122 
 123         return "XML-RPC client (hieu-le/wordpress-xmlrpc-client 2.4.0) PHP {$phpVersion} cUrl {$curlVersion['version']}";
 124     }
 125 
 126     /**
 127      * Get current user agent string
 128      *
 129      * @return string
 130      *
 131      * @since 2.4.0
 132      */
 133     function getUserAgent()
 134     {
 135         return $this->userAgent;
 136     }
 137 
 138     /**
 139      * Set the user agent for next requests
 140      *
 141      * @param string $userAgent custom user agent, give a falsy value to use library user agent
 142      *
 143      * @since 2.4.0
 144      */
 145     function setUserAgent($userAgent)
 146     {
 147         if ($userAgent) {
 148             $this->userAgent = $userAgent;
 149         } else {
 150             $this->userAgent = $this->getDefaultUserAgent();
 151         }
 152     }
 153 
 154     /**
 155      * Get the latest error message
 156      *
 157      * @return string
 158      *
 159      * @since 2.2
 160      */
 161     function getErrorMessage()
 162     {
 163         return $this->error;
 164     }
 165 
 166     /**
 167      * Set the proxy config. To disable proxy, using <code>false</code> as parameter
 168      *
 169      * @param boolean|array $proxyConfig The configuration array has these fields:
 170      *                                   <ul>
 171      *                                   <li><code>proxy_ip</code>: the ip of the proxy server (WITHOUT port)</li>
 172      *                                   <li><code>proxy_port</code>: the port of the proxy server</li>
 173      *                                   <li><code>proxy_user</code>: the username for proxy authorization</li>
 174      *                                   <li><code>proxy_pass</code>: the password for proxy authorization</li>
 175      *                                   <li><code>proxy_mode</code>: value for CURLOPT_PROXYAUTH option (default to
 176      *                                   CURLAUTH_BASIC)</li>
 177      *                                   </ul>
 178      *
 179      * @throws \InvalidArgumentException
 180      * @see   curl_setopt
 181      * @since 2.2
 182      */
 183     function setProxy($proxyConfig)
 184     {
 185         if ($proxyConfig === false || is_array($proxyConfig)) {
 186             $this->proxyConfig = $proxyConfig;
 187         } else {
 188             throw new \InvalidArgumentException(__METHOD__ . " only accept boolean 'false' or an array as parameter.");
 189         }
 190     }
 191 
 192     /**
 193      * Get current proxy config
 194      *
 195      * @return boolean|array
 196      * @since 2.2
 197      */
 198     function getProxy()
 199     {
 200         return $this->proxyConfig;
 201     }
 202 
 203     /**
 204      * Set authentication info
 205      *
 206      * @param boolean|array $authConfig the configuation array
 207      *                                  <ul>
 208      *                                  <li><code>auth_user</code>: the username for server authentication</li>
 209      *                                  <li><code>auth_pass</code>: the password for server authentication</li>
 210      *                                  <li><code>auth_mode</code>: value for CURLOPT_HTTPAUTH option (default to
 211      *                                  CURLAUTH_BASIC)</li>
 212      *                                  </ul>
 213      *
 214      * @throws \InvalidArgumentException
 215      * @see   curl_setopt
 216      * @since 2.2
 217      */
 218     function setAuth($authConfig)
 219     {
 220         if ($authConfig === false || is_array($authConfig)) {
 221             $this->authConfig = $authConfig;
 222         } else {
 223             throw new \InvalidArgumentException(__METHOD__ . " only accept boolean 'false' or an array as parameter.");
 224         }
 225     }
 226 
 227     /**
 228      * Get the current HTTP authentication config
 229      *
 230      * @return type
 231      * @since 2.2
 232      */
 233     function getAuth()
 234     {
 235         return $this->authConfig;
 236     }
 237 
 238     /**
 239      * Retrieve a post of any registered post type.
 240      *
 241      * @param integer $postId the id of selected post
 242      * @param array   $fields (optional) list of field or meta-field names to include in response.
 243      *
 244      * @return array
 245      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.getPosts
 246      */
 247     function getPost($postId, array $fields = array())
 248     {
 249         if (empty($fields)) {
 250             $params = array(1, $this->username, $this->password, $postId);
 251         } else {
 252             $params = array(1, $this->username, $this->password, $postId, $fields);
 253         }
 254 
 255         return $this->sendRequest('wp.getPost', $params);
 256     }
 257 
 258     /**
 259      * Retrieve list of posts of any registered post type.
 260      *
 261      * @param array $filters optional
 262      * @param array $fields  optional
 263      *
 264      * @return array array of struct
 265      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.getPosts
 266      */
 267     function getPosts(array $filters = array(), array $fields = array())
 268     {
 269         $params = array(1, $this->username, $this->password, $filters);
 270         if (!empty($fields)) {
 271             $params[] = $fields;
 272         }
 273 
 274         return $this->sendRequest('wp.getPosts', $params);
 275     }
 276 
 277     /**
 278      * Create a new post of any registered post type.
 279      *
 280      * @param string  $title        the post title
 281      * @param string  $body         the post body
 282      * @param array   $categorieIds the list of category ids
 283      * @param integer $thumbnailId  the thumbnail id
 284      * @param array   $content      the content array, see more at wordpress documentation
 285      *
 286      * @return integer the new post id
 287      *
 288      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.newPost
 289      */
 290     function newPost($title, $body, array $content = array())
 291     {
 292         $default                 = array(
 293             'post_type'   => 'post',
 294             'post_status' => 'publish',
 295         );
 296         $content                 = array_merge($default, $content);
 297         $content['post_title']   = $title;
 298         $content['post_content'] = $body;
 299 
 300         $params = array(1, $this->username, $this->password, $content);
 301 
 302         return $this->sendRequest('wp.newPost', $params);
 303     }
 304 
 305     /**
 306      * Edit an existing post of any registered post type.
 307      *
 308      * @param integer $postId       the id of selected post
 309      * @param string  $title        the new title
 310      * @param string  $body         the new body
 311      * @param array   $categorieIds the new list of category ids
 312      * @param integer $thumbnailId  the new thumbnail id
 313      * @param array   $content      the advanced array
 314      *
 315      * @return boolean
 316      *
 317      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.editPost
 318      */
 319     function editPost($postId, array $content)
 320     {
 321         $params = array(1, $this->username, $this->password, $postId, $content);
 322 
 323         return $this->sendRequest('wp.editPost', $params);
 324     }
 325 
 326     /**
 327      * Delete an existing post of any registered post type.
 328      *
 329      * @param integer $postId the id of selected post
 330      *
 331      * @return boolean
 332      *
 333      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.deletePost
 334      */
 335     function deletePost($postId)
 336     {
 337         $params = array(1, $this->username, $this->password, $postId);
 338 
 339         return $this->sendRequest('wp.deletePost', $params);
 340     }
 341 
 342     /**
 343      * Retrieve a registered post type.
 344      *
 345      * @param string $postTypeName the post type name
 346      * @param array  $fields       (optional) list of field or meta-field names to include in response.
 347      *
 348      * @return array
 349      *
 350      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.getPostType
 351      */
 352     function getPostType($postTypeName, array $fields = array())
 353     {
 354         $params = array(1, $this->username, $this->password, $postTypeName, $fields);
 355 
 356         return $this->sendRequest('wp.getPostType', $params);
 357     }
 358 
 359     /**
 360      * Retrieve list of registered post types.
 361      *
 362      * @param array $filter
 363      * @param array $fields
 364      *
 365      * @return array    list of struct
 366      *
 367      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.getPostTypes
 368      */
 369     function getPostTypes(array $filter = array(), array $fields = array())
 370     {
 371         $params = array(1, $this->username, $this->password, $filter, $fields);
 372 
 373         return $this->sendRequest('wp.getPostTypes', $params);
 374     }
 375 
 376     /**
 377      * Retrieve list of post formats.
 378      *
 379      * @return array
 380      *
 381      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.getPostFormats
 382      */
 383     function getPostFormats()
 384     {
 385         $params = array(1, $this->username, $this->password);
 386 
 387         return $this->sendRequest('wp.getPostFormats', $params);
 388     }
 389 
 390     /**
 391      * Retrieve list of supported values for post_status field on posts.
 392      *
 393      * @return array    list of supported post status
 394      *
 395      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.getPostStatusList
 396      */
 397     function getPostStatusList()
 398     {
 399         $params = array(1, $this->username, $this->password);
 400 
 401         return $this->sendRequest('wp.getPostStatusList', $params);
 402     }
 403 
 404     /**
 405      * Retrieve information about a taxonomy.
 406      *
 407      * @param string $taxonomy the name of the selected taxonomy
 408      *
 409      * @return array    taxonomy information
 410      *
 411      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies#wp.getTaxonomy
 412      */
 413     function getTaxonomy($taxonomy)
 414     {
 415         $params = array(1, $this->username, $this->password, $taxonomy);
 416 
 417         return $this->sendRequest('wp.getTaxonomy', $params);
 418     }
 419 
 420     /**
 421      * Retrieve a list of taxonomies.
 422      *
 423      * @return array array of taxonomy struct
 424      *
 425      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies#wp.getTaxonomies
 426      */
 427     function getTaxonomies()
 428     {
 429         $params = array(1, $this->username, $this->password);
 430 
 431         return $this->sendRequest('wp.getTaxonomies', $params);
 432     }
 433 
 434     /**
 435      * Retrieve a taxonomy term.
 436      *
 437      * @param integer $termId
 438      * @param string  $taxonomy
 439      *
 440      * @return array
 441      *
 442      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies#wp.getTerm
 443      */
 444     function getTerm($termId, $taxonomy)
 445     {
 446         $params = array(1, $this->username, $this->password, $taxonomy, $termId);
 447 
 448         return $this->sendRequest('wp.getTerm', $params);
 449     }
 450 
 451     /**
 452      * Retrieve list of terms in a taxonomy.
 453      *
 454      * @param string $taxonomy
 455      * @param array  $filter
 456      *
 457      * @return array
 458      *
 459      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies#wp.getTerms
 460      */
 461     function getTerms($taxonomy, array $filter = array())
 462     {
 463         $params = array(1, $this->username, $this->password, $taxonomy, $filter);
 464 
 465         return $this->sendRequest('wp.getTerms', $params);
 466     }
 467 
 468     /**
 469      * Create a new taxonomy term.
 470      *
 471      * @param string  $name
 472      * @param string  $taxomony
 473      * @param string  $slug
 474      * @param string  $description
 475      * @param integer $parentId
 476      *
 477      * @return integer new term id
 478      *
 479      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies#wp.newTerm
 480      */
 481     function newTerm($name, $taxomony, $slug = null, $description = null, $parentId = null)
 482     {
 483         $content = array(
 484             'name'     => $name,
 485             'taxonomy' => $taxomony,
 486         );
 487         if ($slug) {
 488             $content['slug'] = $slug;
 489         }
 490         if ($description) {
 491             $content['description'] = $description;
 492         }
 493         if ($parentId) {
 494             $content['parent'] = $parentId;
 495         }
 496         $params = array(1, $this->username, $this->password, $content);
 497 
 498         return $this->sendRequest('wp.newTerm', $params);
 499     }
 500 
 501     /**
 502      * Edit an existing taxonomy term.
 503      *
 504      * @param integer $termId
 505      * @param string  $taxonomy
 506      * @param array   $content
 507      *
 508      * @return boolean
 509      *
 510      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies#wp.editTerm
 511      */
 512     function editTerm($termId, $taxonomy, array $content = array())
 513     {
 514         $content['taxonomy'] = $taxonomy;
 515         $params              = array(1, $this->username, $this->password, $termId, $content);
 516 
 517         return $this->sendRequest('wp.editTerm', $params);
 518     }
 519 
 520     /**
 521      * Delete an existing taxonomy term.
 522      *
 523      * @param integer $termId
 524      * @param string  $taxonomy
 525      *
 526      * @return boolean
 527      *
 528      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Taxonomies#wp.deleteTerm
 529      */
 530     function deleteTerm($termId, $taxonomy)
 531     {
 532         $params = array(1, $this->username, $this->password, $taxonomy, $termId);
 533 
 534         return $this->sendRequest('wp.deleteTerm', $params);
 535     }
 536 
 537     /**
 538      * Retrieve a media item (i.e, attachment).
 539      *
 540      * @param integer $itemId
 541      *
 542      * @return array
 543      *
 544      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Media#wp.getMediaItem
 545      */
 546     function getMediaItem($itemId)
 547     {
 548         $params = array(1, $this->username, $this->password, $itemId);
 549 
 550         return $this->sendRequest('wp.getMediaItem', $params);
 551     }
 552 
 553     /**
 554      * Retrieve list of media items.
 555      *
 556      * @param array $filter
 557      *
 558      * @return array
 559      *
 560      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Media#wp.getMediaLibrary
 561      */
 562     function getMediaLibrary(array $filter = array())
 563     {
 564         $params = array(1, $this->username, $this->password, $filter);
 565 
 566         return $this->sendRequest('wp.getMediaLibrary', $params);
 567     }
 568 
 569     /**
 570      * Upload a media file.
 571      *
 572      * @param string  $name      file name
 573      * @param string  $mime      file mime type
 574      * @param string  $bits      binary data (no encoded)
 575      * @param boolean $overwrite (optional)
 576      * @param int     $postId    (optional)
 577      *
 578      * @return array
 579      *
 580      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Media#wp.uploadFile
 581      */
 582     function uploadFile($name, $mime, $bits, $overwrite = null, $postId = null)
 583     {
 584         xmlrpc_set_type($bits, 'base64');
 585         $struct = array(
 586             'name' => $name,
 587             'type' => $mime,
 588             'bits' => $bits,
 589         );
 590         if ($overwrite !== null) {
 591             $struct['overwrite'] = $overwrite;
 592         }
 593         if ($postId !== null) {
 594             $struct['post_id'] = (int)$postId;
 595         }
 596         $params = array(1, $this->username, $this->password, $struct);
 597 
 598         return $this->sendRequest('wp.uploadFile', $params);
 599     }
 600 
 601     /**
 602      * Retrieve comment count for a specific post.
 603      *
 604      * @param integer $postId
 605      *
 606      * @return integer
 607      *
 608      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Comments#wp.getCommentCount
 609      */
 610     function getCommentCount($postId)
 611     {
 612         $params = array(1, $this->username, $this->password, $postId);
 613 
 614         return $this->sendRequest('wp.getCommentCount', $params);
 615     }
 616 
 617     /**
 618      * Retrieve a comment.
 619      *
 620      * @param integer $commentId
 621      *
 622      * @return array
 623      *
 624      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Comments#wp.getComment
 625      */
 626     function getComment($commentId)
 627     {
 628         $params = array(1, $this->username, $this->password, $commentId);
 629 
 630         return $this->sendRequest('wp.getComment', $params);
 631     }
 632 
 633     /**
 634      * Retrieve list of comments.
 635      *
 636      * @param array $filter
 637      *
 638      * @return array
 639      *
 640      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Comments#wp.getComments
 641      */
 642     function getComments(array $filter = array())
 643     {
 644         $params = array(1, $this->username, $this->password, $filter);
 645 
 646         return $this->sendRequest('wp.getComments', $params);
 647     }
 648 
 649     /**
 650      * Create a new comment.
 651      *
 652      * @param integer $post_id
 653      * @param array   $comment
 654      *
 655      * @return integer new comment_id
 656      *
 657      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Comments#wp.newComment
 658      */
 659     function newComment($post_id, array $comment)
 660     {
 661         $params = array(1, $this->username, $this->password, $post_id, $comment);
 662 
 663         return $this->sendRequest('wp.newComment', $params);
 664     }
 665 
 666     /**
 667      * Edit an existing comment.
 668      *
 669      * @param integer $commentId
 670      * @param array   $comment
 671      *
 672      * @return boolean
 673      *
 674      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Comments#wp.editComment
 675      */
 676     function editComment($commentId, array $comment)
 677     {
 678         $params = array(1, $this->username, $this->password, $commentId, $comment);
 679 
 680         return $this->sendRequest('wp.editComment', $params);
 681     }
 682 
 683     /**
 684      * Remove an existing comment.
 685      *
 686      * @param integer $commentId
 687      *
 688      * @return boolean
 689      *
 690      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Comments#wp.deleteComment
 691      */
 692     function deleteComment($commentId)
 693     {
 694         $params = array(1, $this->username, $this->password, $commentId);
 695 
 696         return $this->sendRequest('wp.deleteComment', $params);
 697     }
 698 
 699     /**
 700      * Retrieve list of comment statuses.
 701      *
 702      * @return array
 703      *
 704      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Comments#wp.getCommentStatusList
 705      */
 706     function getCommentStatusList()
 707     {
 708         $params = array(1, $this->username, $this->password);
 709 
 710         return $this->sendRequest('wp.getCommentStatusList', $params);
 711     }
 712 
 713     /**
 714      * Retrieve blog options.
 715      *
 716      * @param array $options
 717      *
 718      * @return array
 719      *
 720      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Options#wp.getOptions
 721      */
 722     function getOptions(array $options = array())
 723     {
 724         if (empty($options)) {
 725             $params = array(1, $this->username, $this->password);
 726         } else {
 727             $params = array(1, $this->username, $this->password, $options);
 728         }
 729 
 730         return $this->sendRequest('wp.getOptions', $params);
 731     }
 732 
 733     /**
 734      * Edit blog options.
 735      *
 736      * @param array $options
 737      *
 738      * @return array
 739      *
 740      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Options#wp.setOptions
 741      */
 742     function setOptions(array $options)
 743     {
 744         $params = array(1, $this->username, $this->password, $options);
 745 
 746         return $this->sendRequest('wp.setOptions', $params);
 747     }
 748 
 749     /**
 750      * Retrieve list of blogs for this user.
 751      *
 752      * @return array
 753      *
 754      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Users#wp.getUsersBlogs
 755      */
 756     function getUsersBlogs()
 757     {
 758         $params = array($this->username, $this->password);
 759 
 760         return $this->sendRequest('wp.getUsersBlogs', $params);
 761     }
 762 
 763     /**
 764      * Retrieve a user.
 765      *
 766      * @param integer $userId
 767      * @param array   $fields Optional. List of field or meta-field names to include in response.
 768      *
 769      * @return array
 770      *
 771      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Users#wp.getUser
 772      */
 773     function getUser($userId, array $fields = array())
 774     {
 775         $params = array(1, $this->username, $this->password, $userId);
 776         if (!empty($fields)) {
 777             $params[] = $fields;
 778         }
 779 
 780         return $this->sendRequest('wp.getUser', $params);
 781     }
 782 
 783     /**
 784      * Retrieve list of users.
 785      *
 786      * @param array $filters
 787      * @param array $fields
 788      *
 789      * @return array
 790      *
 791      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Users#wp.getUsers
 792      */
 793     function getUsers(array $filters = array(), array $fields = array())
 794     {
 795         $params = array(1, $this->username, $this->password, $filters);
 796         if (!empty($fields)) {
 797             $params[] = $fields;
 798         }
 799 
 800         return $this->sendRequest('wp.getUsers', $params);
 801     }
 802 
 803     /**
 804      * Retrieve profile of the requesting user.
 805      *
 806      * @param array $fields
 807      *
 808      * @return array
 809      *
 810      * @link http://codex.wordpress.org/XML-RPC_WordPress_API/Users#wp.getProfile
 811      */
 812     function getProfile(array $fields = array())
 813     {
 814         $params = array(1, $this->username, $this->password);
 815         if (!empty($fields)) {
 816             $params[] = $fields;
 817         }
 818 
 819         return $this->sendRequest('wp.getProfile', $params);
 820     }
 821 
 822     /**
 823      * Edit profile of the requesting user.
 824      *
 825      * @param array $content
 826      *
 827      * @return boolean
 828      *
 829      * http://codex.wordpress.org/XML-RPC_WordPress_API/Users#wp.editProfile
 830      */
 831     function editProfile(array $content)
 832     {
 833         $params = array(1, $this->username, $this->password, $content);
 834 
 835         return $this->sendRequest('wp.editProfile', $params);
 836     }
 837 
 838     /**
 839      * Call a custom XML-RPC method
 840      *
 841      * @param string $method the method name
 842      * @param array  $params the parameters of this call
 843      *
 844      * @return mixed
 845      *
 846      * @since 2.3.0
 847      */
 848     public function callCustomMethod($method, $params)
 849     {
 850         return $this->sendRequest($method, $params);
 851     }
 852 
 853     /**
 854      * Create an XMLRPC DateTime object
 855      *
 856      * @param \DateTime $datetime
 857      *
 858      * @return string with the XMLRPC internal type is set to datetime
 859      */
 860     public function createXMLRPCDateTime($datetime)
 861     {
 862         $value = $datetime->format('Ymd\TH:i:sO');
 863         xmlrpc_set_type($value, 'datetime');
 864 
 865         return $value;
 866     }
 867 
 868     protected function performRequest()
 869     {
 870         if (function_exists('curl_init')) {
 871             return $this->requestWithCurl();
 872         } else {
 873             return $this->requestWithFile();
 874         }
 875     }
 876 
 877     protected function getRequest()
 878     {
 879         return $this->request;
 880     }
 881 
 882     private function sendRequest($method, $params)
 883     {
 884         if (!$this->endPoint) {
 885             $this->error = "Invalid endpoint " . json_encode(array(
 886                     'endpoint' => $this->endPoint,
 887                     'username' => $this->username,
 888                     'password' => $this->password,
 889                 ));
 890             $this->logError();
 891             throw new \Exception($this->error);
 892         }
 893         $this->responseHeader = array();
 894 
 895         // This block is used for compatibility with the older version of this package, which run on PHP < 7.0.
 896         // Since the 2.5.0 version, the datetime must be set explicitly by using the `createXMLRPCDateTime` method.
 897         if (version_compare(PHP_VERSION, '7.0.0', '<')) {
 898             $this->setXmlrpcType($params);
 899         }
 900 
 901         $this->request = xmlrpc_encode_request($method, $params,
 902             array('encoding' => 'UTF-8', 'escaping' => 'markup', 'version' => 'xmlrpc'));
 903         $body          = "";
 904         // Call sending event callbacks
 905         $callbacks = $this->getCallback('sending');
 906         $event     = array(
 907             'event'    => 'sending',
 908             'endpoint' => $this->endPoint,
 909             'username' => $this->username,
 910             'password' => $this->password,
 911             'method'   => $method,
 912             'params'   => $params,
 913             'request'  => $this->request,
 914             'proxy'    => $this->proxyConfig,
 915             'auth'     => $this->authConfig,
 916         );
 917         foreach ($callbacks as $callback) {
 918             call_user_func($callback, $event);
 919         }
 920         $body     = $this->performRequest();
 921         $response = xmlrpc_decode($body, 'UTF-8');
 922         if (is_array($response) && xmlrpc_is_fault($response)) {
 923             $this->error = ("xmlrpc: {$response['faultString']} ({$response['faultCode']})");
 924             $this->logError();
 925             throw new Exception\XmlrpcException($response['faultString'], $response['faultCode']);
 926         }
 927 
 928         return $response;
 929     }
 930 
 931     /**
 932      * Set the correct type for each element in an array
 933      *
 934      * @param array $array
 935      *
 936      * @since 2.2
 937      */
 938     private function setXmlrpcType(&$array)
 939     {
 940         foreach ($array as $key => $element) {
 941             if (is_a($element, '\DateTime')) {
 942                 $array[$key] = $element->format("Ymd\TH:i:sO");
 943                 xmlrpc_set_type($array[$key], 'datetime');
 944             } elseif (is_array($element)) {
 945                 $this->setXmlrpcType($array[$key]);
 946             }
 947         }
 948     }
 949 
 950     private function requestWithCurl()
 951     {
 952         $ch = curl_init($this->endPoint);
 953         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 954         curl_setopt($ch, CURLOPT_POST, 1);
 955         curl_setopt($ch, CURLOPT_POSTFIELDS, $this->request);
 956         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
 957         curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
 958         if ($this->proxyConfig != false) {
 959             if (isset($this->proxyConfig['proxy_ip'])) {
 960                 curl_setopt($ch, CURLOPT_PROXY, $this->proxyConfig['proxy_ip']);
 961             }
 962             if (isset($this->proxyConfig['proxy_port'])) {
 963                 curl_setopt($ch, CURLOPT_PROXYPORT, $this->proxyConfig['proxy_port']);
 964             }
 965             if (isset($this->proxyConfig['proxy_user']) && isset($this->proxyConfig['proxy_pass'])) {
 966                 curl_setopt($ch, CURLOPT_PROXYUSERPWD,
 967                     "{$this->proxyConfig['proxy_user']}:{$this->proxyConfig['proxy_pass']}");
 968             }
 969             if (isset($this->proxyConfig['proxy_mode'])) {
 970                 curl_setopt($ch, CURLOPT_PROXYAUTH, $this->proxyConfig['proxy_mode']);
 971             }
 972         }
 973         if ($this->authConfig) {
 974             if (isset($this->authConfig['auth_user']) && isset($this->authConfig['auth_pass'])) {
 975                 curl_setopt($ch, CURLOPT_USERPWD,
 976                     "{$this->authConfig['auth_user']}:{$this->authConfig['auth_pass']}");
 977                 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
 978             }
 979             if (isset($this->authConfig['auth_mode'])) {
 980                 curl_setopt($ch, CURLOPT_HTTPAUTH, $this->authConfig['auth_mode']);
 981             }
 982         }
 983         $response = curl_exec($ch);
 984         if (curl_errno($ch)) {
 985             $message     = curl_error($ch);
 986             $code        = curl_errno($ch);
 987             $this->error = "curl: {$message} ({$code})";
 988             $this->logError();
 989             curl_close($ch);
 990             throw new Exception\NetworkException($message, $code);
 991         }
 992         $httpStatusCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
 993         if ($httpStatusCode >= 400) {
 994             $message     = $response;
 995             $code        = $httpStatusCode;
 996             $this->error = "http: {$message} ({$code})";
 997             $this->logError();
 998             curl_close($ch);
 999             throw new Exception\NetworkException($message, $code);
1000         }
1001         curl_close($ch);
1002 
1003         return $response;
1004     }
1005 
1006     private function requestWithFile()
1007     {
1008         $contextOptions = array(
1009             'http' => array(
1010                 'method'     => "POST",
1011                 'user_agent' => $this->userAgent,
1012                 'header'     => "Content-Type: text/xml\r\n",
1013                 'content'    => $this->request,
1014             ),
1015         );
1016 
1017         if ($this->proxyConfig != false) {
1018             if (isset($this->proxyConfig['proxy_ip']) && isset($this->proxyConfig['proxy_port'])) {
1019                 $contextOptions['http']['proxy']           = "tcp://{$this->proxyConfig['proxy_ip']}:{$this->proxyConfig['proxy_port']}";
1020                 $contextOptions['http']['request_fulluri'] = true;
1021             }
1022             if (isset($this->proxyConfig['proxy_user']) && isset($this->proxyConfig['proxy_pass'])) {
1023                 $auth = base64_encode("{$this->proxyConfig['proxy_user']}:{$this->proxyConfig['proxy_pass']}");
1024                 $contextOptions['http']['header'] .= "Proxy-Authorization: Basic {$auth}\r\n";
1025             }
1026             if (isset($this->proxyConfig['proxy_mode'])) {
1027                 throw new \InvalidArgumentException('Cannot use NTLM proxy authorization without cURL extension');
1028             }
1029         }
1030         if ($this->authConfig) {
1031             if (isset($this->authConfig['auth_user']) && isset($this->authConfig['auth_pass'])) {
1032                 $auth = base64_encode("{$this->authConfig['auth_user']}:{$this->authConfig['auth_pass']}");
1033                 $contextOptions['http']['header'] .= "Authorization: Basic {$auth}\r\n";
1034             }
1035             if (isset($this->authConfig['auth_mode'])) {
1036                 throw new \InvalidArgumentException('Cannot use other authentication method without cURL extension');
1037             }
1038         }
1039         $context              = stream_context_create($contextOptions);
1040         $http_response_header = array();
1041         try {
1042             $file = @file_get_contents($this->endPoint, false, $context);
1043             if ($file === false) {
1044                 $error       = error_get_last();
1045                 $error       = $error ? trim($error['message']) : "error";
1046                 $this->error = "file_get_contents: {$error}";
1047                 $this->logError();
1048                 throw new Exception\NetworkException($error, 127);
1049             }
1050         } catch (\Exception $ex) {
1051             $this->error = ("file_get_contents: {$ex->getMessage()} ({$ex->getCode()})");
1052             $this->logError();
1053             throw new Exception\NetworkException($ex->getMessage(), $ex->getCode());
1054         }
1055 
1056         return $file;
1057     }
1058 
1059     private function logError()
1060     {
1061         $callbacks = $this->getCallback('error');
1062         $event     = array(
1063             'event'    => 'error',
1064             'endpoint' => $this->endPoint,
1065             'request'  => $this->request,
1066             'proxy'    => $this->proxyConfig,
1067             'auth'     => $this->authConfig,
1068         );
1069         foreach ($callbacks as $callback) {
1070             call_user_func($callback, $this->error, $event);
1071         }
1072     }
1073 
1074     private function getCallback($name)
1075     {
1076         $callbacks = array();
1077         if (isset($this->_callbacks[$name]) && is_array($this->_callbacks[$name])) {
1078             $callbacks = $this->_callbacks[$name];
1079         }
1080 
1081         return $callbacks;
1082     }
1083 
1084 }
1085 
Wordpress XML-RPC PHP Client API documentation generated by ApiGen