Elgg  Version 2.3
Service.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Ajax;
4 
12 
20 class Service {
21 
25  private $hooks;
26 
30  private $msgs;
31 
35  private $input;
36 
40  private $amd_config;
41 
45  private $response_sent = false;
46 
50  private $allowed_views = [];
51 
60  public function __construct(PluginHooksService $hooks, SystemMessagesService $msgs, Input $input, Config $amdConfig) {
61  $this->hooks = $hooks;
62  $this->msgs = $msgs;
63  $this->input = $input;
64  $this->amd_config = $amdConfig;
65 
66  if ($this->input->get('elgg_fetch_messages', true)) {
67  $message_filter = [$this, 'appendMessages'];
68  $this->hooks->registerHandler(AjaxResponse::RESPONSE_HOOK, 'all', $message_filter, 999);
69  }
70 
71  if ($this->input->get('elgg_fetch_deps', true)) {
72  $deps_filter = [$this, 'appendDeps'];
73  $this->hooks->registerHandler(AjaxResponse::RESPONSE_HOOK, 'all', $deps_filter, 999);
74  }
75  }
76 
82  public function isAjax2Request() {
83  $version = _elgg_services()->request->headers->get('X-Elgg-Ajax-API');
84  return ($version === '2');
85  }
86 
96  public function isReady() {
97  return !$this->response_sent && $this->isAjax2Request();
98  }
99 
106  public function decodeJson($string) {
107  if (!is_string($string)) {
108  return $string;
109  }
110  $object = json_decode($string);
111  return ($object === null) ? $string : $object;
112  }
113 
122  public function respondFromOutput($output, $hook_type = '', $try_decode = true) {
123  if ($try_decode) {
124  $output = $this->decodeJson($output);
125  }
126 
127  $api_response = new Response();
128  $api_response->setData((object)[
129  'value' => $output,
130  ]);
131  $api_response = $this->filterApiResponse($api_response, $hook_type);
132  $response = $this->buildHttpResponse($api_response);
133 
134  $this->response_sent = true;
135  return _elgg_services()->responseFactory->send($response);
136  }
137 
145  public function respondFromApiResponse(AjaxResponse $api_response, $hook_type = '') {
146  $api_response = $this->filterApiResponse($api_response, $hook_type);
147  $response = $this->buildHttpResponse($api_response);
148 
149  $this->response_sent = true;
150  return _elgg_services()->responseFactory->send($response);
151  }
152 
160  public function respondWithError($msg = '', $status = 400) {
161  $response = new JsonResponse(['error' => $msg], $status);
162 
163  $this->response_sent = true;
164  return _elgg_services()->responseFactory->send($response);
165  }
166 
175  private function filterApiResponse(AjaxResponse $api_response, $hook_type = '') {
176  $api_response->setTtl($this->input->get('elgg_response_ttl', 0, false));
177 
178  if ($hook_type) {
180  $api_response = $this->hooks->trigger($hook, $hook_type, null, $api_response);
181  if (!$api_response instanceof AjaxResponse) {
182  throw new RuntimeException("The value returned by hook [$hook, $hook_type] was not an ApiResponse");
183  }
184  }
185 
186  return $api_response;
187  }
188 
198  private function buildHttpResponse(AjaxResponse $api_response, $allow_removing_headers = null) {
199  if ($api_response->isCancelled()) {
200  return new JsonResponse(['error' => "The response was cancelled"], 400);
201  }
202 
203  $response = new JsonResponse($api_response->getData());
204 
205  $ttl = $api_response->getTtl();
206  if ($ttl > 0) {
207  // Required to remove headers set by PHP session
208  if (!isset($allow_removing_headers)) {
209  $allow_removing_headers = !elgg()->isTestingApplication();
210  }
211 
212  if ($allow_removing_headers) {
213  header_remove('Expires');
214  header_remove('Pragma');
215  header_remove('Cache-Control');
216  }
217 
218  // JsonRequest sets a default Cache-Control header we don't want
219  $response->headers->remove('Cache-Control');
220 
221  $response->setClientTtl($ttl);
222 
223  // if we don't set Expires, Apache will add a far-off max-age and Expires for us.
224  $response->headers->set('Expires', gmdate('D, d M Y H:i:s \G\M\T', time() + $ttl));
225  }
226 
227  return $response;
228  }
229 
242  public function appendMessages($hook, $type, $response, $params) {
243  if (!$response instanceof AjaxResponse) {
244  return;
245  }
246  $response->getData()->_elgg_msgs = (object)$this->msgs->dumpRegister();
247  return $response;
248  }
249 
262  public function appendDeps($hook, $type, $response, $params) {
263  if (!$response instanceof AjaxResponse) {
264  return;
265  }
266  $response->getData()->_elgg_deps = (array) $this->amd_config->getDependencies();
267  return $response;
268  }
269 
276  public function registerView($view) {
277  $this->allowed_views[$view] = true;
278  }
279 
286  public function unregisterView($view) {
287  unset($this->allowed_views[$view]);
288  }
289 
294  public function getViews() {
295  return array_keys($this->allowed_views);
296  }
297 
298 }
elgg
Definition: install.js:23
$object
These two snippets demonstrates triggering an event and how to register for that event.
Definition: trigger.php:7
$view
Definition: crop.php:34
isCancelled()
Has the response been cancelled?
$version
unregisterView($view)
Unregister a view for ajax calls.
Definition: Service.php:286
setTtl($ttl=0)
Set the max-age for client caching.
isAjax2Request()
Did the request come from the elgg/Ajax module?
Definition: Service.php:82
appendDeps($hook, $type, $response, $params)
Send required AMD modules list back with the response.
Definition: Service.php:262
Models the Ajax API service.
Definition: Service.php:20
$string
$params
Definition: login.php:72
__construct(PluginHooksService $hooks, SystemMessagesService $msgs, Input $input, Config $amdConfig)
Constructor.
Definition: Service.php:60
registerView($view)
Register a view to be available for ajax calls.
Definition: Service.php:276
decodeJson($string)
Attempt to JSON decode the given string.
Definition: Service.php:106
JSON endpoint response.
Definition: AjaxResponse.php:9
respondFromOutput($output, $hook_type= '', $try_decode=true)
Send a JSON HTTP response with the given output.
Definition: Service.php:122
$amdConfig
respondFromApiResponse(AjaxResponse $api_response, $hook_type= '')
Send a JSON HTTP response based on the given API response.
Definition: Service.php:145
_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".
elgg subtext time
appendMessages($hook, $type, $response, $params)
Send system messages back with the response.
Definition: Service.php:242
isReady()
Is the service ready to respond to the request?
Definition: Service.php:96
JSON endpoint response.
Definition: Response.php:11
$output
Definition: item.php:10
elgg table input[type=checkbox]
Definition: admin.css.php:404
getTtl()
Get the max-age for client caching.
http free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:5
getViews()
Returns an array of views allowed for ajax calls.
Definition: Service.php:294
respondWithError($msg= '', $status=400)
Send a JSON HTTP 400 response.
Definition: Service.php:160
if(!$display_name) $type
Definition: delete.php:27