[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/kissifrot/php-ixr/src/Client/ -> Client.php (source)

   1  <?php
   2  namespace IXR\Client;
   3  
   4  use IXR\Message\Error;
   5  use IXR\Message\Message;
   6  use IXR\Request\Request;
   7  
   8  /**
   9   * IXR_Client
  10   *
  11   * @package IXR
  12   * @since   1.5.0
  13   *
  14   */
  15  class Client
  16  {
  17      protected $server;
  18      protected $port;
  19      protected $path;
  20      protected $useragent;
  21      protected $response;
  22      /** @var bool|Message */
  23      protected $message = false;
  24      protected $debug = false;
  25      /** @var int Connection timeout in seconds */
  26      protected $timeout;
  27      /** @var null|int Timeout for actual data transfer; in seconds */
  28      protected $timeout_io = null;
  29      protected $headers = [];
  30  
  31      /**
  32       * @var null|Error
  33       *
  34       * Storage place for an error message
  35       */
  36      private $error = null;
  37  
  38      public function __construct($server, $path = false, $port = 80, $timeout = 15, $timeout_io = null)
  39      {
  40          if (!$path) {
  41              // Assume we have been given a URL instead
  42              $bits = parse_url($server);
  43              $this->server = $bits['host'];
  44              $this->port = isset($bits['port']) ? $bits['port'] : 80;
  45              $this->path = isset($bits['path']) ? $bits['path'] : '/';
  46  
  47              // Make absolutely sure we have a path
  48              if (!$this->path) {
  49                  $this->path = '/';
  50              }
  51  
  52              if (!empty($bits['query'])) {
  53                  $this->path .= '?' . $bits['query'];
  54              }
  55          } else {
  56              $this->server = $server;
  57              $this->path = $path;
  58              $this->port = $port;
  59          }
  60          $this->useragent = 'The Incutio XML-RPC PHP Library';
  61          $this->timeout = $timeout;
  62          $this->timeout_io = $timeout_io;
  63      }
  64  
  65      public function query()
  66      {
  67          $args = func_get_args();
  68          $method = array_shift($args);
  69          $request = new Request($method, $args);
  70          $length = $request->getLength();
  71          $xml = $request->getXml();
  72          $r = "\r\n";
  73          $request = "POST {$this->path} HTTP/1.0$r";
  74  
  75          // Merged from WP #8145 - allow custom headers
  76          $this->headers['Host'] = $this->server;
  77          $this->headers['Content-Type'] = 'text/xml';
  78          $this->headers['User-Agent'] = $this->useragent;
  79          $this->headers['Content-Length'] = $length;
  80  
  81          foreach ($this->headers as $header => $value) {
  82              $request .= "{$header}: {$value}{$r}";
  83          }
  84          $request .= $r;
  85  
  86          $request .= $xml;
  87  
  88          // Now send the request
  89          if ($this->debug) {
  90              echo '<pre class="ixr_request">' . htmlspecialchars($request) . "\n</pre>\n\n";
  91          }
  92  
  93          if ($this->timeout) {
  94              try {
  95                  $fp = fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout);
  96              } catch (\Exception $e) {
  97                  $fp = false;
  98              }
  99          } else {
 100              try {
 101                  $fp = fsockopen($this->server, $this->port, $errno, $errstr);
 102              } catch (\Exception $e) {
 103                  $fp = false;
 104              }
 105          }
 106          if (!$fp) {
 107              return $this->handleError(-32300, 'transport error - could not open socket');
 108          }
 109          if (null !== $this->timeout_io) {
 110              stream_set_timeout($fp, $this->timeout_io);
 111          }
 112          fputs($fp, $request);
 113          $contents = '';
 114          $debugContents = '';
 115          $gotFirstLine = false;
 116          $gettingHeaders = true;
 117          while (!feof($fp)) {
 118              $line = fgets($fp, 4096);
 119              if (!$gotFirstLine) {
 120                  // Check line for '200'
 121                  if (strstr($line, '200') === false) {
 122                      return $this->handleError(-32300, 'transport error - HTTP status code was not 200');
 123                  }
 124                  $gotFirstLine = true;
 125              }
 126              if (trim($line) == '') {
 127                  $gettingHeaders = false;
 128              }
 129              if (!$gettingHeaders) {
 130                  // merged from WP #12559 - remove trim
 131                  $contents .= $line;
 132              }
 133              if ($this->debug) {
 134                  $debugContents .= $line;
 135              }
 136          }
 137          if ($this->debug) {
 138              echo '<pre class="ixr_response">' . htmlspecialchars($debugContents) . "\n</pre>\n\n";
 139          }
 140  
 141          // Now parse what we've got back
 142          $this->message = new Message($contents);
 143          if (!$this->message->parse()) {
 144              // XML error
 145              return $this->handleError(-32700, 'Parse error. Message not well formed');
 146          }
 147  
 148          // Is the message a fault?
 149          if ($this->message->messageType == 'fault') {
 150              return $this->handleError($this->message->faultCode, $this->message->faultString);
 151          }
 152  
 153          // Message must be OK
 154          return true;
 155      }
 156  
 157      public function getResponse()
 158      {
 159          // methodResponses can only have one param - return that
 160          return $this->message->params[0];
 161      }
 162  
 163      public function isError()
 164      {
 165          return (is_object($this->error));
 166      }
 167  
 168      protected function handleError($errorCode, $errorMessage)
 169      {
 170          $this->error = new Error($errorCode, $errorMessage);
 171  
 172          return false;
 173      }
 174  
 175      public function getError()
 176      {
 177          return $this->error;
 178      }
 179  
 180      public function getErrorCode()
 181      {
 182          return $this->error->code;
 183      }
 184  
 185      public function getErrorMessage()
 186      {
 187          return $this->error->message;
 188      }
 189  
 190  
 191      /**
 192       * Gets the current timeout set for data transfer
 193       * @return int|null
 194       */
 195      public function getTimeoutIo()
 196      {
 197          return $this->timeout_io;
 198      }
 199  
 200      /**
 201       * Sets the timeout for data transfer
 202       * @param int $timeout_io
 203       * @return $this
 204       */
 205      public function setTimeoutIo($timeout_io)
 206      {
 207          $this->timeout_io = $timeout_io;
 208      }
 209  }