Elgg  Version master
Service.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Ajax;
4 
12 use PHPUnit\Util\Json;
13 use Symfony\Component\HttpFoundation\JsonResponse;
14 
21 class Service {
22 
23  protected bool $response_sent = false;
24 
25  protected array $allowed_views = [];
26 
36  public function __construct(
37  protected EventsService $events,
38  protected SystemMessagesService $msgs,
39  protected Request $request,
40  protected ESMService $esm,
41  protected ExternalFiles $externalFiles
42  ) {
43  }
44 
50  public function isAjax2Request(): bool {
51  return $this->request->headers->get('X-Elgg-Ajax-API') === '2';
52  }
53 
63  public function isReady(): bool {
64  return !$this->response_sent && $this->isAjax2Request();
65  }
66 
74  public function decodeJson($string) {
75  if (!is_string($string)) {
76  return $string;
77  }
78 
79  $object = json_decode($string);
80  return ($object === null) ? $string : $object;
81  }
82 
92  public function respondFromOutput(mixed $output, string $event_type = '', bool $try_decode = true): JsonResponse|false {
93  if ($try_decode) {
94  $output = $this->decodeJson($output);
95  }
96 
97  if (is_object($output) && isset($output->value)) {
98  $data = $output;
99  } elseif (is_array($output) && isset($output['value'])) {
100  $data = (object) $output;
101  } else {
102  $data = (object) ['value' => $output];
103  }
104 
105  if ($event_type) {
106  $data = (object) $this->events->triggerResults('ajax_results', $event_type, [], $data);
107  }
108 
109  if (!property_exists($data, 'value')) {
110  throw new InvalidArgumentException('$data must have a property "value"');
111  }
112 
113  if ($this->request->getParam('elgg_fetch_messages', true)) {
114  $messages = $this->msgs->dumpRegister();
115  foreach ($messages as $type => $msgs) {
116  $messages[$type] = array_map(function($value) {
117  return (string) $value;
118  }, $msgs);
119  }
120 
121  $data->_elgg_msgs = (object) $messages;
122  }
123 
124  if ($this->request->getParam('elgg_fetch_deps', true)) {
125  $deps = [
126  'js' => $this->esm->getImports(),
127  'css' => [],
128  ];
129 
130  foreach ($this->externalFiles->getLoadedResources('css', 'head') as $name => $resource) {
131  if ($name === 'elgg') {
132  // prevent loading of elgg.css in admin context
133  continue;
134  }
135 
136  $deps['css'][] = [
137  'name' => $name,
138  'href' => $resource->url,
139  'integrity' => $resource->integrity,
140  ];
141  }
142 
143  $data->_elgg_deps = $deps;
144  }
145 
146  $response = _elgg_services()->responseFactory->prepareJsonResponse($data);
147  $response->setTtl((int) $this->request->getParam('elgg_response_ttl', 0, false));
148 
149  $this->response_sent = true;
150  return _elgg_services()->responseFactory->send($response);
151  }
152 
161  public function respondWithError(string $msg = '', int $status = 400): JsonResponse|false {
162  $response = new JsonResponse(['error' => $msg], $status);
163 
164  // clear already set system messages as we respond directly with an error as message body
165  $this->msgs->dumpRegister();
166 
167  $this->response_sent = true;
168  return _elgg_services()->responseFactory->send($response);
169  }
170 
178  public function registerView(string $view): void {
179  $this->allowed_views[$view] = true;
180  }
181 
189  public function unregisterView(string $view): void {
190  unset($this->allowed_views[$view]);
191  }
192 
198  public function getViews(): array {
199  return array_keys($this->allowed_views);
200  }
201 }
if(! $user||! $user->canDelete()) $name
Definition: delete.php:22
if(!empty($avatar) &&! $avatar->isValid()) elseif(empty($avatar)) if(! $owner->saveIconFromUploadedFile('avatar')) if(!elgg_trigger_event('profileiconupdate', $owner->type, $owner)) $view
Definition: upload.php:39
$type
Definition: delete.php:21
catch(AuthenticationException|LoginException $e) if(elgg_is_xhr()) $output
Definition: login.php:86
return[ 'admin/delete_admin_notices'=>['access'=> 'admin'], 'admin/menu/save'=>['access'=> 'admin'], 'admin/plugins/activate'=>['access'=> 'admin'], 'admin/plugins/activate_all'=>['access'=> 'admin'], 'admin/plugins/deactivate'=>['access'=> 'admin'], 'admin/plugins/deactivate_all'=>['access'=> 'admin'], 'admin/plugins/set_priority'=>['access'=> 'admin'], 'admin/security/security_txt'=>['access'=> 'admin'], 'admin/security/settings'=>['access'=> 'admin'], 'admin/security/regenerate_site_secret'=>['access'=> 'admin'], 'admin/site/cache/clear'=>['access'=> 'admin'], 'admin/site/cache/invalidate'=>['access'=> 'admin'], 'admin/site/icons'=>['access'=> 'admin'], 'admin/site/set_maintenance_mode'=>['access'=> 'admin'], 'admin/site/set_robots'=>['access'=> 'admin'], 'admin/site/theme'=>['access'=> 'admin'], 'admin/site/unlock_upgrade'=>['access'=> 'admin'], 'admin/site/settings'=>['access'=> 'admin'], 'admin/upgrade'=>['access'=> 'admin'], 'admin/upgrade/reset'=>['access'=> 'admin'], 'admin/user/ban'=>['access'=> 'admin'], 'admin/user/bulk/ban'=>['access'=> 'admin'], 'admin/user/bulk/delete'=>['access'=> 'admin'], 'admin/user/bulk/unban'=>['access'=> 'admin'], 'admin/user/bulk/validate'=>['access'=> 'admin'], 'admin/user/change_email'=>['access'=> 'admin'], 'admin/user/delete'=>['access'=> 'admin'], 'admin/user/login_as'=>['access'=> 'admin'], 'admin/user/logout_as'=>[], 'admin/user/makeadmin'=>['access'=> 'admin'], 'admin/user/resetpassword'=>['access'=> 'admin'], 'admin/user/removeadmin'=>['access'=> 'admin'], 'admin/user/unban'=>['access'=> 'admin'], 'admin/user/validate'=>['access'=> 'admin'], 'annotation/delete'=>[], 'avatar/upload'=>[], 'comment/save'=>[], 'diagnostics/download'=>['access'=> 'admin', 'controller'=> \Elgg\Diagnostics\DownloadController::class,], 'entity/chooserestoredestination'=>[], 'entity/delete'=>[], 'entity/mute'=>[], 'entity/restore'=>[], 'entity/subscribe'=>[], 'entity/trash'=>[], 'entity/unmute'=>[], 'entity/unsubscribe'=>[], 'login'=>['access'=> 'logged_out'], 'logout'=>[], 'notifications/mute'=>['access'=> 'public'], 'plugins/settings/remove'=>['access'=> 'admin'], 'plugins/settings/save'=>['access'=> 'admin'], 'plugins/usersettings/save'=>[], 'register'=>['access'=> 'logged_out', 'middleware'=>[\Elgg\Router\Middleware\RegistrationAllowedGatekeeper::class,],], 'river/delete'=>[], 'settings/notifications'=>[], 'settings/notifications/subscriptions'=>[], 'user/changepassword'=>['access'=> 'public'], 'user/requestnewpassword'=>['access'=> 'public'], 'useradd'=>['access'=> 'admin'], 'usersettings/save'=>[], 'widgets/add'=>[], 'widgets/delete'=>[], 'widgets/move'=>[], 'widgets/save'=>[],]
Definition: actions.php:76
if(! $entity instanceof \ElggUser) $data
Definition: attributes.php:13
Models the Ajax API service.
Definition: Service.php:21
isAjax2Request()
Did the request come from the elgg/Ajax module?
Definition: Service.php:50
__construct(protected EventsService $events, protected SystemMessagesService $msgs, protected Request $request, protected ESMService $esm, protected ExternalFiles $externalFiles)
Constructor.
Definition: Service.php:36
array $allowed_views
Definition: Service.php:25
bool $response_sent
Definition: Service.php:23
registerView(string $view)
Register a view to be available for ajax calls.
Definition: Service.php:178
isReady()
Is the service ready to respond to the request?
Definition: Service.php:63
respondWithError(string $msg='', int $status=400)
Send a JSON HTTP 400 response.
Definition: Service.php:161
getViews()
Returns an array of views allowed for ajax calls.
Definition: Service.php:198
respondFromOutput(mixed $output, string $event_type='', bool $try_decode=true)
Send a JSON HTTP response with the given output.
Definition: Service.php:92
decodeJson($string)
Attempt to JSON decode the given string.
Definition: Service.php:74
unregisterView(string $view)
Unregister a view for ajax calls.
Definition: Service.php:189
External files service.
Events service.
Exception thrown if an argument is not of the expected type.
Exception thrown if an error which can only be found on runtime occurs.
Elgg HTTP request.
Definition: Request.php:17
Keeps track of ES modules.
Definition: ESMService.php:16
System messages service.
if($email instanceof \Elgg\Email) $object
Definition: body.php:24
if(!empty($children)) elseif($item->getData('show_with_empty_children')===false) $deps
Definition: item.php:54
if($item instanceof \ElggEntity) elseif($item instanceof \ElggRiverItem) elseif($item instanceof \ElggRelationship) elseif(is_callable([ $item, 'getType']))
Definition: item.php:48
_elgg_services()
Get the global service provider.
Definition: elgglib.php:343
$value
Definition: generic.php:51
$request
Definition: livesearch.php:12
$resource
if(parse_url(elgg_get_site_url(), PHP_URL_PATH) !=='/') if(file_exists(elgg_get_root_path() . 'robots.txt'))
Set robots.txt.
Definition: robots.php:10
$messages
Definition: admin.php:12
$response
Definition: content.php:10