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