AmfphpGet.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. /**
  3. * This file is part of amfPHP
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the license that is bundled
  8. * with this package in the file license.txt.
  9. */
  10. /**
  11. * Adds support for HTTP GET requests to services, useful for simple test calls and for cross domain ajax calls.
  12. * This plugin can be deactivated if the project doesn't use GET requests.
  13. *
  14. * Cross Domain Ajax calls are normally not possible for security reasons, but by using a hack you can get around it.
  15. * This however must be done with HTTP GET. So this plugin is specifically for requesting json data from amfPHP using HTTP GET.
  16. * This comes with some limitations: GET is limited in size, and you can't send complex objects.
  17. * If you're on the same domain, you're probably better off using the AmfphpJson plugin as these limitations don't apply.
  18. *
  19. * You must add the 'text/amfphpget' content type, or set it in the headers so that it is recognized as a call to be handled by this plugin.
  20. * for example:
  21. * http://yourserver.com/?contentType=text/amfphpget&serviceName=YourService&methodName=yourMethod&p01=value1&p2=value2 etc.
  22. *
  23. * If you are using this for crossdomain ajax with JSONP, the expected format of the request is to add the extra 'callback' parameter.
  24. * If no callback id is found, the answer simply contains the json encoded return data.
  25. * If the callback is found, the answer is wrapped so that it can be used for JSONP.
  26. *
  27. * Thanks to nViso.ch who needed the cross domain ajax functionality.
  28. *
  29. * Requires at least PHP 5.2.
  30. *
  31. * @see http://remysharp.com/2007/10/08/what-is-jsonp/
  32. * @see http://usejquery.com/posts/9/the-jquery-cross-domain-ajax-guide
  33. * @package Amfphp_Plugins_Get
  34. * @author Ariel Sommeria-Klein.
  35. */
  36. class AmfphpGet implements Amfphp_Core_Common_IDeserializer, Amfphp_Core_Common_IDeserializedRequestHandler, Amfphp_Core_Common_IExceptionHandler, Amfphp_Core_Common_ISerializer {
  37. /**
  38. * the content-type string indicating a cross domain ajax call
  39. */
  40. const CONTENT_TYPE = 'text/amfphpget';
  41. /**
  42. * return error details.
  43. * @see Amfphp_Core_Config::CONFIG_RETURN_ERROR_DETAILS
  44. * @var boolean
  45. */
  46. protected $returnErrorDetails = false;
  47. /**
  48. * constructor. Add filters on the HookManager.
  49. * @param array $config optional key/value pairs in an associative array. Used to override default configuration values.
  50. */
  51. public function __construct(array $config = null) {
  52. $filterManager = Amfphp_Core_FilterManager::getInstance();
  53. $filterManager->addFilter(Amfphp_Core_Gateway::FILTER_DESERIALIZER, $this, 'filterHandler');
  54. $filterManager->addFilter(Amfphp_Core_Gateway::FILTER_DESERIALIZED_REQUEST_HANDLER, $this, 'filterHandler');
  55. $filterManager->addFilter(Amfphp_Core_Gateway::FILTER_EXCEPTION_HANDLER, $this, 'filterHandler');
  56. $filterManager->addFilter(Amfphp_Core_Gateway::FILTER_SERIALIZER, $this, 'filterHandler');
  57. $filterManager->addFilter(Amfphp_Core_Gateway::FILTER_HEADERS, $this, 'filterHeaders');
  58. $this->returnErrorDetails = (isset ($config[Amfphp_Core_Config::CONFIG_RETURN_ERROR_DETAILS]) && $config[Amfphp_Core_Config::CONFIG_RETURN_ERROR_DETAILS]);
  59. }
  60. /**
  61. * If the content type contains the 'json' string, returns this plugin
  62. * @param mixed null at call in gateway.
  63. * @param String $contentType
  64. * @return this or null
  65. */
  66. public function filterHandler($handler, $contentType){
  67. if(strpos($contentType, self::CONTENT_TYPE) !== false){
  68. return $this;
  69. }
  70. }
  71. /**
  72. * deserialize
  73. * @see Amfphp_Core_Common_IDeserializer
  74. * @param array $getData
  75. * @param array $postData
  76. * @param string $rawPostData
  77. * @return string
  78. */
  79. public function deserialize(array $getData, array $postData, $rawPostData){
  80. return $getData;
  81. }
  82. /**
  83. * Retrieve the serviceName, methodName and parameters from the PHP object
  84. * representing the JSON string
  85. * call service
  86. * @see Amfphp_Core_Common_IDeserializedRequestHandler
  87. * @param array $deserializedRequest
  88. * @param Amfphp_Core_Common_ServiceRouter $serviceRouter
  89. * @return the service call response
  90. */
  91. public function handleDeserializedRequest($deserializedRequest, Amfphp_Core_Common_ServiceRouter $serviceRouter){
  92. if(isset ($deserializedRequest['serviceName'])){
  93. $serviceName = $deserializedRequest['serviceName'];
  94. }else{
  95. throw new Exception('Service name field missing in call parameters \n' . print_r($deserializedRequest, true));
  96. }
  97. if(isset ($deserializedRequest['methodName'])){
  98. $methodName = $deserializedRequest['methodName'];
  99. }else{
  100. throw new Exception('MethodName field missing in call parameters \n' . print_r($deserializedRequest, true));
  101. }
  102. $parameters = array();
  103. $paramCounter = 1;
  104. while(isset ($deserializedRequest["p$paramCounter"])){
  105. $parameters[] = $deserializedRequest["p$paramCounter"];
  106. $paramCounter++;
  107. }
  108. return $serviceRouter->executeServiceCall($serviceName, $methodName, $parameters);
  109. }
  110. /**
  111. * handle exception
  112. * @see Amfphp_Core_Common_IExceptionHandler
  113. * @param Exception $exception
  114. * @return stdClass
  115. */
  116. public function handleException(Exception $exception){
  117. $error = new stdClass();
  118. $error->message = $exception->getMessage();
  119. $error->code = $exception->getCode();
  120. if($this->returnErrorDetails){
  121. $error->file = $exception->getFile();
  122. $error->line = $exception->getLine();
  123. $error->stack = $exception->getTraceAsString();
  124. }
  125. return (object)array('error' => $error);
  126. }
  127. /**
  128. * Encode the PHP object returned from the service call into a JSON string
  129. * @see Amfphp_Core_Common_ISerializer
  130. * @param mixed $data
  131. * @return string the encoded JSON string sent to JavaScript
  132. */
  133. public function serialize($data){
  134. $encoded = json_encode($data);
  135. if(isset ($_GET['callback'])){
  136. return $_GET['callback'] . '(' . $encoded . ');';
  137. }else{
  138. return $encoded;
  139. }
  140. }
  141. /**
  142. * sets return content type to json
  143. * @param array $headers
  144. * @param string $contentType
  145. * @return array
  146. */
  147. public function filterHeaders($headers, $contentType){
  148. if ($contentType == self::CONTENT_TYPE) {
  149. $headers['Content-Type'] = 'application/json';
  150. return $headers;
  151. }
  152. }
  153. }
  154. ?>