XRL  2.0.0
Simple XML-RPC Library (both client and server)
Server.php
1 <?php
2 /*
3  * This file is part of XRL, a simple XML-RPC Library for PHP.
4  *
5  * Copyright (c) 2012, XRL Team. All rights reserved.
6  * XRL is licensed under the 3-clause BSD License.
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace fpoirotte\XRL;
13 
15 
68 {
70  protected $XRLFunctions;
71 
73  protected $XRLEncoder;
74 
76  protected $XRLDecoder;
77 
78 
97  public function __construct(
98  \fpoirotte\XRL\EncoderInterface $encoder = null,
99  \fpoirotte\XRL\DecoderInterface $decoder = null
100  ) {
101  if ($encoder === null) {
102  $encoder = new \fpoirotte\XRL\NativeEncoder(
103  new \fpoirotte\XRL\Encoder(null, false, true)
104  );
105  }
106 
107  if ($decoder === null) {
108  $decoder = new \fpoirotte\XRL\NativeDecoder(
109  new \fpoirotte\XRL\Decoder(null, true)
110  );
111  }
112 
113  $this->XRLEncoder = $encoder;
114  $this->XRLDecoder = $decoder;
115  $this->XRLFunctions = array();
116  }
117 
139  public function __set($func, $callback)
140  {
141  $this->XRLFunctions[$func] = new \fpoirotte\XRL\CallableObject($callback);
142  }
143 
149  public function offsetSet($func, $callback)
150  {
151  $this->XRLFunctions[$func] = new \fpoirotte\XRL\CallableObject($callback);
152  }
153 
174  public function __get($func)
175  {
176  return $this->XRLFunctions[$func];
177  }
178 
184  public function offsetGet($func)
185  {
186  return $this->XRLFunctions[$func];
187  }
188 
201  public function __isset($func)
202  {
203  return isset($this->XRLFunctions[$func]);
204  }
205 
211  public function offsetExists($func)
212  {
213  return isset($this->XRLFunctions[$func]);
214  }
215 
227  public function __unset($func)
228  {
229  unset($this->XRLFunctions[$func]);
230  }
231 
237  public function offsetUnset($func)
238  {
239  unset($this->XRLFunctions[$func]);
240  }
241 
250  public function count()
251  {
252  return count($this->XRLFunctions);
253  }
254 
263  public function getIterator()
264  {
265  return new \ArrayIterator($this->XRLFunctions);
266  }
267 
292  public function expose($other, $prefix = '')
293  {
294  if (!is_string($other) && !is_object($other)) {
295  throw new \InvalidArgumentException('Invalid adoption');
296  }
297 
298  if (!is_string($prefix)) {
299  throw new \InvalidArgumentException('Invalid prefix');
300  }
301 
302  $prefix = rtrim($prefix, '.');
303  if ($prefix !== '') {
304  $prefix .= '.';
305  }
306 
307  if (is_object($other)) {
308  // An object was passed.
309  $class = get_class($other);
310  foreach (get_class_methods($class) as $method) {
311  // Only adopt public methods of the object,
312  // excluding the constructor and static methods.
313  // To also register static methods, call this method
314  // a second time with get_class($other).
315  $reflector = new \ReflectionMethod($class, $method);
316  if ($reflector->isPublic() && !$reflector->isConstructor() &&
317  !$reflector->isStatic()) {
318  $this[$prefix . $method] = array($other, $method);
319  }
320  }
321  } else {
322  // A class was passed.
323  foreach (get_class_methods($other) as $method) {
324  // Only adopt methods which are both public and static.
325  $reflector = new \ReflectionMethod($other, $method);
326  if ($reflector->isPublic() && $reflector->isStatic()) {
327  $this[$prefix . $method] = array($other, $method);
328  }
329  }
330  }
331  }
332 
354  public function handle($URI = null)
355  {
356  if ($URI === null) {
357  $URI = 'php://input';
358  }
359 
360  try {
361  $request = $this->XRLDecoder->decodeRequest($URI);
362  $procedure = $request->getProcedure();
363  // Necessary to keep references.
364  $params = $request->getParams();
365 
366  $result = $this->call($procedure, $params);
367  $response = $this->XRLEncoder->encodeResponse($result);
368  } catch (\Exception $result) {
369  $response = $this->XRLEncoder->encodeError($result);
370  }
371 
372  return new \fpoirotte\XRL\Response($response);
373  }
374 
387  public function call($procedure, array $params)
388  {
389  if (!is_string($procedure)) {
390  throw new \BadFunctionCallException('Expected a string');
391  }
392 
393  if (!isset($this->XRLFunctions[$procedure])) {
394  throw \fpoirotte\XRL\Faults::get(\fpoirotte\XRL\Faults::METHOD_NOT_FOUND);
395  }
396 
397  $callable = $this->XRLFunctions[$procedure];
398  return $callable->invokeArgs($params);
399  }
400 }
Interface to provide accessing objects as arrays.
Definition: ArrayAccess.php:10
Interface for an XML-RPC decoder.
Interface for an XML-RPC encoder.
$XRLEncoder
Encoder for the request.
Definition: Server.php:73
Interface to create an external Iterator.
An XML-RPC encoder that can produce either compact documents or pretty documents. ...
Definition: Encoder.php:21
handle($URI=null)
Definition: Server.php:354
An exception that is used to represent XML-RPC errors.
Definition: Exception.php:21
call($procedure, array $params)
Definition: Server.php:387
A simple XML-RPC server.
Definition: Server.php:67
offsetSet($func, $callback)
Definition: Server.php:149
$XRLFunctions
Registered "procedures".
Definition: Server.php:70
A decoder that can process XML-RPC requests and responses, with optional XML validation.
Definition: Decoder.php:21
$XRLDecoder
Decoder for the response.
Definition: Server.php:76
__construct(\fpoirotte\XRL\EncoderInterface $encoder=null,\fpoirotte\XRL\DecoderInterface $decoder=null)
Definition: Server.php:97
const METHOD_NOT_FOUND
Alias for the corresponding interoperability fault.
Definition: Faults.php:80
expose($other, $prefix= '')
Definition: Server.php:292
Classes implementing Countable can be used with the count() function.
Definition: Countable.php:11
__set($func, $callback)
Definition: Server.php:139