Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
Service.php
Go to the documentation of this file.
1 <?php
2 namespace Elgg\Ajax;
3 
9 use RuntimeException;
10 use Symfony\Component\HttpFoundation\JsonResponse;
11 
19 class Service {
20 
24  private $hooks;
25 
29  private $msgs;
30 
34  private $input;
35 
39  private $amd_config;
40 
44  private $response_sent = false;
45 
54  public function __construct(PluginHooksService $hooks, SystemMessagesService $msgs, Input $input, Config $amdConfig) {
55  $this->hooks = $hooks;
56  $this->msgs = $msgs;
57  $this->input = $input;
58  $this->amd_config = $amdConfig;
59 
60  if ($this->input->get('elgg_fetch_messages', true)) {
61  $message_filter = [$this, 'appendMessages'];
62  $this->hooks->registerHandler(AjaxResponse::RESPONSE_HOOK, 'all', $message_filter, 999);
63  }
64 
65  if ($this->input->get('elgg_fetch_deps', true)) {
66  $deps_filter = [$this, 'appendDeps'];
67  $this->hooks->registerHandler(AjaxResponse::RESPONSE_HOOK, 'all', $deps_filter, 999);
68  }
69  }
70 
76  public function isAjax2Request() {
77  $version = _elgg_services()->request->headers->get('X-Elgg-Ajax-API');
78  return ($version === '2');
79  }
80 
90  public function isReady() {
91  return !$this->response_sent && $this->isAjax2Request();
92  }
93 
100  public function decodeJson($string) {
101  if (!is_string($string)) {
102  return $string;
103  }
104  $object = json_decode($string);
105  return ($object === null) ? $string : $object;
106  }
107 
116  public function respondFromOutput($output, $hook_type = '', $try_decode = true) {
117  if ($try_decode) {
118  $output = $this->decodeJson($output);
119  }
120 
121  $api_response = new Response();
122  $api_response->setData((object)[
123  'value' => $output,
124  ]);
125  $api_response = $this->filterApiResponse($api_response, $hook_type);
126  $response = $this->buildHttpResponse($api_response);
127 
128  $this->response_sent = true;
129  $response->send();
130  }
131 
139  public function respondFromApiResponse(AjaxResponse $api_response, $hook_type = '') {
140  $api_response = $this->filterApiResponse($api_response, $hook_type);
141  $response = $this->buildHttpResponse($api_response);
142 
143  $this->response_sent = true;
144  $response->send();
145  }
146 
154  public function respondWithError($msg, $status = 400) {
155  $response = new JsonResponse(['error' => $msg], $status);
156 
157  $this->response_sent = true;
158  $response->send();
159  }
160 
169  private function filterApiResponse(AjaxResponse $api_response, $hook_type = '') {
170  $api_response->setTtl($this->input->get('elgg_response_ttl', 0, false));
171 
172  if ($hook_type) {
174  $api_response = $this->hooks->trigger($hook, $hook_type, null, $api_response);
175  if (!$api_response instanceof AjaxResponse) {
176  throw new RuntimeException("The value returned by hook [$hook, $hook_type] was not an ApiResponse");
177  }
178  }
179 
180  return $api_response;
181  }
182 
192  private function buildHttpResponse(AjaxResponse $api_response, $allow_removing_headers = true) {
193  if ($api_response->isCancelled()) {
194  return new JsonResponse(['error' => "The response was cancelled"], 400);
195  }
196 
197  $response = new JsonResponse($api_response->getData());
198 
199  $ttl = $api_response->getTtl();
200  if ($ttl > 0) {
201  // Required to remove headers set by PHP session
202  if ($allow_removing_headers) {
203  header_remove('Expires');
204  header_remove('Pragma');
205  header_remove('Cache-Control');
206  }
207 
208  // JsonRequest sets a default Cache-Control header we don't want
209  $response->headers->remove('Cache-Control');
210 
211  $response->setClientTtl($ttl);
212 
213  // if we don't set Expires, Apache will add a far-off max-age and Expires for us.
214  $response->headers->set('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl));
215  }
216 
217  return $response;
218  }
219 
232  public function appendMessages($hook, $type, AjaxResponse $response, $params) {
233  $response->getData()->_elgg_msgs = (object)$this->msgs->dumpRegister();
234  return $response;
235  }
236 
249  public function appendDeps($hook, $type, AjaxResponse $response, $params) {
250  $response->getData()->_elgg_deps = (array) $this->amd_config->getDependencies();
251  return $response;
252  }
253 
254 }
$object
These two snippets demonstrates triggering an event and how to register for that event.
Definition: trigger.php:7
setTtl($ttl=0)
Set the max-age for client caching.
isAjax2Request()
Did the request come from the elgg/Ajax module?
Definition: Service.php:76
appendMessages($hook, $type, AjaxResponse $response, $params)
Send system messages back with the response.
Definition: Service.php:232
Models the Ajax API service.
Definition: Service.php:19
$string
$params
Definition: login.php:72
__construct(PluginHooksService $hooks, SystemMessagesService $msgs, Input $input, Config $amdConfig)
Constructor.
Definition: Service.php:54
decodeJson($string)
Attempt to JSON decode the given string.
Definition: Service.php:100
JSON endpoint response.
Definition: AjaxResponse.php:9
appendDeps($hook, $type, AjaxResponse $response, $params)
Send required AMD modules list back with the response.
Definition: Service.php:249
respondFromOutput($output, $hook_type= '', $try_decode=true)
Send a JSON HTTP response with the given output.
Definition: Service.php:116
$amdConfig
respondFromApiResponse(AjaxResponse $api_response, $hook_type= '')
Send a JSON HTTP response based on the given API response.
Definition: Service.php:139
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
getData()
Get the response data, which will be a stdClass object with property "value".
isReady()
Is the service ready to respond to the request?
Definition: Service.php:90
JSON endpoint response.
Definition: Response.php:11
$output
Definition: item.php:10
elgg river item input[type=text]
$version
Definition: version.php:14
respondWithError($msg, $status=400)
Send a JSON HTTP 400 response.
Definition: Service.php:154
if(!$display_name) $type
Definition: delete.php:27