Added the zend framework 2 library, the path is specified in line no.26 in zend_modul...
[openemr.git] / interface / modules / zend_modules / library / Zend / Json / Server / Server.php
blob1da0bff9124269210d1397fa344b448822fde73d
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Json\Server;
12 use ReflectionFunction;
13 use ReflectionMethod;
14 use Zend\Server\AbstractServer;
15 use Zend\Server\Definition;
16 use Zend\Server\Method;
17 use Zend\Server\Reflection;
19 class Server extends AbstractServer
21 /**#@+
22 * Version Constants
24 const VERSION_1 = '1.0';
25 const VERSION_2 = '2.0';
26 /**#@-*/
28 /**
29 * Flag: whether or not to auto-emit the response
30 * @var bool
32 protected $returnResponse = false;
34 /**
35 * Inherited from Zend\Server\AbstractServer
37 * @var bool Flag; allow overwriting existing methods when creating server definition
39 protected $overwriteExistingMethods = true;
41 /**
42 * Request object
43 * @var Request
45 protected $request;
47 /**
48 * Response object
49 * @var Response
51 protected $response;
53 /**
54 * SMD object
55 * @var Smd
57 protected $serviceMap;
59 /**
60 * SMD class accessors
61 * @var array
63 protected $smdMethods;
65 /**
66 * Attach a function or callback to the server
68 * @param string|array|callable $function Valid PHP callback
69 * @param string $namespace Ignored
70 * @throws Exception\InvalidArgumentException if function invalid or not callable
71 * @return Server
73 public function addFunction($function, $namespace = '')
75 if (!is_string($function) && (!is_array($function) || (2 > count($function)))) {
76 throw new Exception\InvalidArgumentException('Unable to attach function; invalid');
79 if (!is_callable($function)) {
80 throw new Exception\InvalidArgumentException('Unable to attach function; does not exist');
83 $argv = null;
84 if (2 < func_num_args()) {
85 $argv = func_get_args();
86 $argv = array_slice($argv, 2);
89 $class = null;
90 if (is_string($function)) {
91 $method = Reflection::reflectFunction($function, $argv, $namespace);
92 } else {
93 $class = array_shift($function);
94 $action = array_shift($function);
95 $reflection = Reflection::reflectClass($class, $argv, $namespace);
96 $methods = $reflection->getMethods();
97 $found = false;
98 foreach ($methods as $method) {
99 if ($action == $method->getName()) {
100 $found = true;
101 break;
104 if (!$found) {
105 $this->fault('Method not found', Error::ERROR_INVALID_METHOD);
106 return $this;
110 $definition = $this->_buildSignature($method, $class);
111 $this->_addMethodServiceMap($definition);
113 return $this;
117 * Register a class with the server
119 * @param string $class
120 * @param string $namespace Ignored
121 * @param mixed $argv Ignored
122 * @return Server
124 public function setClass($class, $namespace = '', $argv = null)
126 if (2 < func_num_args()) {
127 $argv = func_get_args();
128 $argv = array_slice($argv, 2);
131 $reflection = Reflection::reflectClass($class, $argv, $namespace);
133 foreach ($reflection->getMethods() as $method) {
134 $definition = $this->_buildSignature($method, $class);
135 $this->_addMethodServiceMap($definition);
137 return $this;
141 * Indicate fault response
143 * @param string $fault
144 * @param int $code
145 * @param mixed $data
146 * @return Error
148 public function fault($fault = null, $code = 404, $data = null)
150 $error = new Error($fault, $code, $data);
151 $this->getResponse()->setError($error);
152 return $error;
156 * Handle request
158 * @param Request $request
159 * @return null|Response
160 * @throws Exception\InvalidArgumentException
162 public function handle($request = false)
164 if ((false !== $request) && (!$request instanceof Request)) {
165 throw new Exception\InvalidArgumentException('Invalid request type provided; cannot handle');
166 } elseif ($request) {
167 $this->setRequest($request);
170 // Handle request
171 $this->_handle();
173 // Get response
174 $response = $this->_getReadyResponse();
176 // Emit response?
177 if (!$this->returnResponse) {
178 echo $response;
179 return;
182 // or return it?
183 return $response;
187 * Load function definitions
189 * @param array|Definition $definition
190 * @throws Exception\InvalidArgumentException
191 * @return void
193 public function loadFunctions($definition)
195 if (!is_array($definition) && (!$definition instanceof Definition)) {
196 throw new Exception\InvalidArgumentException('Invalid definition provided to loadFunctions()');
199 foreach ($definition as $key => $method) {
200 $this->table->addMethod($method, $key);
201 $this->_addMethodServiceMap($method);
205 public function setPersistence($mode)
210 * Set request object
212 * @param Request $request
213 * @return Server
215 public function setRequest(Request $request)
217 $this->request = $request;
218 return $this;
222 * Get JSON-RPC request object
224 * @return Request
226 public function getRequest()
228 if (null === ($request = $this->request)) {
229 $this->setRequest(new Request\Http());
231 return $this->request;
235 * Set response object
237 * @param Response $response
238 * @return Server
240 public function setResponse(Response $response)
242 $this->response = $response;
243 return $this;
247 * Get response object
249 * @return Response
251 public function getResponse()
253 if (null === ($response = $this->response)) {
254 $this->setResponse(new Response\Http());
256 return $this->response;
260 * Set return response flag
262 * If true, {@link handle()} will return the response instead of
263 * automatically sending it back to the requesting client.
265 * The response is always available via {@link getResponse()}.
267 * @param bool $flag
268 * @return Server
270 public function setReturnResponse($flag = true)
272 $this->returnResponse = ($flag) ? true : false;
273 return $this;
277 * Retrieve return response flag
279 * @return bool
281 public function getReturnResponse()
283 return $this->returnResponse;
286 // overloading for SMD metadata
288 * Overload to accessors of SMD object
290 * @param string $method
291 * @param array $args
292 * @return mixed
294 public function __call($method, $args)
296 if (preg_match('/^(set|get)/', $method, $matches)) {
297 if (in_array($method, $this->_getSmdMethods())) {
298 if ('set' == $matches[1]) {
299 $value = array_shift($args);
300 $this->getServiceMap()->$method($value);
301 return $this;
302 } else {
303 return $this->getServiceMap()->$method();
307 return null;
311 * Retrieve SMD object
313 * @return Smd
315 public function getServiceMap()
317 if (null === $this->serviceMap) {
318 $this->serviceMap = new Smd();
320 return $this->serviceMap;
324 * Add service method to service map
326 * @param Method\Definition $method
327 * @return void
329 protected function _addMethodServiceMap(Method\Definition $method)
331 $serviceInfo = array(
332 'name' => $method->getName(),
333 'return' => $this->_getReturnType($method),
335 $params = $this->_getParams($method);
336 $serviceInfo['params'] = $params;
337 $serviceMap = $this->getServiceMap();
338 if (false !== $serviceMap->getService($serviceInfo['name'])) {
339 $serviceMap->removeService($serviceInfo['name']);
341 $serviceMap->addService($serviceInfo);
345 * Translate PHP type to JSON type
347 * @param string $type
348 * @return string
350 protected function _fixType($type)
352 return $type;
356 * Get default params from signature
358 * @param array $args
359 * @param array $params
360 * @return array
362 protected function _getDefaultParams(array $args, array $params)
364 $defaultParams = array_slice($params, count($args));
365 foreach ($defaultParams as $param) {
366 $value = null;
367 if (array_key_exists('default', $param)) {
368 $value = $param['default'];
370 $args[$param['name']] = $value;
372 return $args;
376 * Get method param type
378 * @param Method\Definition $method
379 * @return string|array
381 protected function _getParams(Method\Definition $method)
383 $params = array();
384 foreach ($method->getPrototypes() as $prototype) {
385 foreach ($prototype->getParameterObjects() as $key => $parameter) {
386 if (!isset($params[$key])) {
387 $params[$key] = array(
388 'type' => $parameter->getType(),
389 'name' => $parameter->getName(),
390 'optional' => $parameter->isOptional(),
392 if (null !== ($default = $parameter->getDefaultValue())) {
393 $params[$key]['default'] = $default;
395 $description = $parameter->getDescription();
396 if (!empty($description)) {
397 $params[$key]['description'] = $description;
399 continue;
401 $newType = $parameter->getType();
402 if (!is_array($params[$key]['type'])) {
403 if ($params[$key]['type'] == $newType) {
404 continue;
406 $params[$key]['type'] = (array) $params[$key]['type'];
407 } elseif (in_array($newType, $params[$key]['type'])) {
408 continue;
410 array_push($params[$key]['type'], $parameter->getType());
413 return $params;
417 * Set response state
419 * @return Response
421 protected function _getReadyResponse()
423 $request = $this->getRequest();
424 $response = $this->getResponse();
426 $response->setServiceMap($this->getServiceMap());
427 if (null !== ($id = $request->getId())) {
428 $response->setId($id);
430 if (null !== ($version = $request->getVersion())) {
431 $response->setVersion($version);
434 return $response;
438 * Get method return type
440 * @param Method\Definition $method
441 * @return string|array
443 protected function _getReturnType(Method\Definition $method)
445 $return = array();
446 foreach ($method->getPrototypes() as $prototype) {
447 $return[] = $prototype->getReturnType();
449 if (1 == count($return)) {
450 return $return[0];
452 return $return;
456 * Retrieve list of allowed SMD methods for proxying
458 * @return array
460 protected function _getSmdMethods()
462 if (null === $this->smdMethods) {
463 $this->smdMethods = array();
464 $methods = get_class_methods('Zend\\Json\\Server\\Smd');
465 foreach ($methods as $method) {
466 if (!preg_match('/^(set|get)/', $method)) {
467 continue;
469 if (strstr($method, 'Service')) {
470 continue;
472 $this->smdMethods[] = $method;
475 return $this->smdMethods;
479 * Internal method for handling request
481 * @return void
483 protected function _handle()
485 $request = $this->getRequest();
487 if($request->isParseError()){
488 return $this->fault('Parse error', Error::ERROR_PARSE);
491 if (!$request->isMethodError() && (null === $request->getMethod())) {
492 return $this->fault('Invalid Request', Error::ERROR_INVALID_REQUEST);
495 if ($request->isMethodError()) {
496 return $this->fault('Invalid Request', Error::ERROR_INVALID_REQUEST);
499 $method = $request->getMethod();
500 if (!$this->table->hasMethod($method)) {
501 return $this->fault('Method not found', Error::ERROR_INVALID_METHOD);
504 $params = $request->getParams();
505 $invokable = $this->table->getMethod($method);
506 $serviceMap = $this->getServiceMap();
507 $service = $serviceMap->getService($method);
508 $serviceParams = $service->getParams();
510 if (count($params) < count($serviceParams)) {
511 $params = $this->_getDefaultParams($params, $serviceParams);
514 //Make sure named parameters are passed in correct order
515 if (is_string(key($params))) {
516 $callback = $invokable->getCallback();
517 if ('function' == $callback->getType()) {
518 $reflection = new ReflectionFunction($callback->getFunction());
519 } else {
521 $reflection = new ReflectionMethod(
522 $callback->getClass(),
523 $callback->getMethod()
527 $orderedParams = array();
528 foreach ($reflection->getParameters() as $refParam) {
529 if (array_key_exists($refParam->getName(), $params)) {
530 $orderedParams[$refParam->getName()] = $params[$refParam->getName()];
531 } elseif ($refParam->isOptional()) {
532 $orderedParams[$refParam->getName()] = null;
533 } else {
534 return $this->fault('Invalid params', Error::ERROR_INVALID_PARAMS);
537 $params = $orderedParams;
540 try {
541 $result = $this->_dispatch($invokable, $params);
542 } catch (\Exception $e) {
543 return $this->fault($e->getMessage(), $e->getCode(), $e);
546 $this->getResponse()->setResult($result);