Elgg  Version 4.3
UserCapabilities.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
9 use ElggEntity;
10 use ElggFile;
11 use ElggRiverItem;
12 use ElggSession;
13 
21 
25  private $hooks;
26 
30  private $entities;
31 
35  private $session;
36 
44  public function __construct(PluginHooksService $hooks, EntityTable $entities, ElggSession $session) {
45  $this->hooks = $hooks;
46  $this->entities = $entities;
47  $this->session = $session;
48  }
49 
61  public function canBypassPermissionsCheck($user_guid = 0) {
62  if ($this->session->getIgnoreAccess()) {
63  // Checking ignored access first to avoid infinite loops,
64  // when trying to fetch a user by guid
65  return true;
66  }
67 
68  try {
69  $user = $this->entities->getUserForPermissionsCheck($user_guid);
70  } catch (UserFetchFailureException $e) {
71  return false;
72  }
73 
74  return $user && $user->isAdmin();
75  }
76 
87  public function canEdit(ElggEntity $entity, $user_guid = 0) {
88  if ($this->canBypassPermissionsCheck($user_guid)) {
89  return true;
90  }
91 
92  try {
93  $user = $this->entities->getUserForPermissionsCheck($user_guid);
94  } catch (UserFetchFailureException $e) {
95  return false;
96  }
97 
98  // Test user if possible - should default to false unless a plugin hook says otherwise
99  $default = call_user_func(function () use ($entity, $user) {
100  if (!$user) {
101  return false;
102  }
103 
104  // favor the persisted attributes if not saved
105  $attrs = array_merge(
106  [
107  'owner_guid' => $entity->owner_guid,
108  'container_guid' => $entity->container_guid,
109  ], $entity->getOriginalAttributes()
110  );
111 
112  if ($attrs['owner_guid'] == $user->guid) {
113  return true;
114  }
115 
116  if ($attrs['container_guid'] == $user->guid) {
117  return true;
118  }
119 
120  if ($entity->guid == $user->guid) {
121  return true;
122  }
123 
124  $container = $this->entities->get($attrs['container_guid']);
125 
126  return ($container && $container->canEdit($user->guid));
127  });
128 
129  $params = ['entity' => $entity, 'user' => $user];
130  return $this->hooks->trigger('permissions_check', $entity->getType(), $params, $default);
131  }
132 
144  public function canDelete(ElggEntity $entity, $user_guid = 0) {
145  if ($this->canBypassPermissionsCheck($user_guid)) {
146  return true;
147  }
148 
149  try {
150  $user = $this->entities->getUserForPermissionsCheck($user_guid);
151  } catch (UserFetchFailureException $e) {
152  return false;
153  }
154 
155  $return = $entity->canEdit($user_guid);
156 
157  $params = [
158  'entity' => $entity,
159  'user' => $user
160  ];
161  return $this->hooks->trigger('permissions_check:delete', $entity->getType(), $params, $return);
162  }
163 
176  if ($this->canBypassPermissionsCheck($user_guid)) {
177  return true;
178  }
179 
180  try {
181  $user = $this->entities->getUserForPermissionsCheck($user_guid);
182  } catch (UserFetchFailureException $e) {
183  return false;
184  }
185 
186  $params = [
187  'item' => $item,
188  'user' => $user,
189  ];
190  return $this->hooks->trigger('permissions_check:delete', 'river', $params, false);
191  }
192 
203  if (!$annotation) {
204  return false;
205  }
206 
207  if ($this->canBypassPermissionsCheck($user_guid)) {
208  return true;
209  }
210 
211  try {
212  $user = $this->entities->getUserForPermissionsCheck($user_guid);
213  } catch (UserFetchFailureException $e) {
214  return false;
215  }
216 
217  $result = false;
218 
219  if ($user) {
220  // If the owner of annotation is the specified user, they can edit.
221  if ($annotation->owner_guid == $user->guid) {
222  $result = true;
223  }
224 
225  // If the user can edit the entity this is attached to, they can edit.
226  if ($result === false && $entity->canEdit($user->guid)) {
227  $result = true;
228  }
229  }
230 
231  // Trigger plugin hook - note that $user may be null
232  $params = [
233  'entity' => $entity,
234  'user' => $user,
235  'annotation' => $annotation
236  ];
237 
238  return $this->hooks->trigger('permissions_check', 'annotation', $params, $result);
239  }
240 
251  public function canWriteToContainer(ElggEntity $entity, string $type, string $subtype, int $user_guid = 0) {
252  try {
253  $user = $this->entities->getUserForPermissionsCheck($user_guid);
254  } catch (UserFetchFailureException $e) {
255  return false;
256  }
257 
258  if ($user) {
259  $user_guid = $user->guid;
260  }
261 
262  $params = [
263  'container' => $entity,
264  'user' => $user,
265  'subtype' => $subtype
266  ];
267 
268  // Unlike permissions, logic check can be used to prevent certain entity
269  // types from being contained by other entity types,
270  // e.g. discussion reply objects can only be contained by discussion objects.
271  // This hook can also be used to apply status logic, e.g. to disallow
272  // new replies in closed discussions.
273  // We do not take a stand hence the return is null. This can be used by
274  // handlers to check if another hook has modified the value.
275  $logic_check = $this->hooks->trigger('container_logic_check', $type, $params);
276 
277  if ($logic_check === false) {
278  return false;
279  }
280 
281  if ($this->canBypassPermissionsCheck($user_guid)) {
282  return true;
283  }
284 
285  // If the user can edit the container, they can also write to it
286  $return = $entity->canEdit($user_guid);
287 
288  // Container permissions can prevent users from writing to an entity.
289  // For instance, these permissions can prevent non-group members from writing
290  // content to the group.
291  return $this->hooks->trigger('container_permissions_check', $type, $params, $return);
292  }
293 
306  public function canComment(ElggEntity $entity, $user_guid = 0, $default = null) {
307  try {
308  $user = $this->entities->getUserForPermissionsCheck($user_guid);
309  } catch (UserFetchFailureException $e) {
310  return false;
311  }
312 
313  $container_result = $this->canWriteToContainer($entity, 'object', 'comment', $user_guid);
314  if ($this->canBypassPermissionsCheck($user_guid)) {
315  // doing this again here to prevent bypassed users to be influenced by permissions_check:comment hook
316  return $container_result;
317  }
318 
319  if (is_null($default) || $default === $container_result) {
320  $default = $container_result;
321  } else {
322  elgg_deprecated_notice('Passing "$default" to $entity->canComment() has been deprecated.', '4.1');
323  }
324 
325  // By default, we don't take a position of whether commenting is allowed
326  // because it is handled by the subclasses of \ElggEntity
327  $params = [
328  'entity' => $entity,
329  'user' => $user,
330  ];
331  return $this->hooks->trigger('permissions_check:comment', $entity->getType(), $params, $default);
332  }
333 
349  public function canAnnotate(ElggEntity $entity, $user_guid = 0, $annotation_name = '') {
350  if ($annotation_name === null || $annotation_name === false) {
351  // accepting these for BC
352  $annotation_name = '';
353  } elseif (!is_string($annotation_name)) {
354  throw new InvalidArgumentException(__METHOD__ . ' expects \$annotation_name to be a string');
355  }
356 
357  if ($this->canBypassPermissionsCheck($user_guid)) {
358  return true;
359  }
360 
361  try {
362  $user = $this->entities->getUserForPermissionsCheck($user_guid);
363  } catch (UserFetchFailureException $e) {
364  return false;
365  }
366 
367  $return = (bool) $user;
368 
369  $params = [
370  'entity' => $entity,
371  'user' => $user,
372  'annotation_name' => $annotation_name,
373  ];
374 
375  if (!empty($annotation_name)) {
376  $return = $this->hooks->trigger("permissions_check:annotate:$annotation_name", $entity->getType(), $params, $return);
377  }
378 
379  return $this->hooks->trigger('permissions_check:annotate', $entity->getType(), $params, $return);
380  }
381 
393  public function canDownload(ElggFile $entity, $user_guid = 0, $default = true) {
394  if ($this->canBypassPermissionsCheck($user_guid)) {
395  return true;
396  }
397 
398  try {
399  $user = $this->entities->getUserForPermissionsCheck($user_guid);
400  } catch (UserFetchFailureException $e) {
401  return false;
402  }
403 
404  $params = [
405  'entity' => $entity,
406  'user' => $user
407  ];
408 
409  return $this->hooks->trigger('permissions_check:download', 'file', $params, $default);
410  }
411 
412 }
$default
Definition: checkbox.php:31
if(!$items) $item
Definition: delete.php:13
canDeleteRiverItem(ElggRiverItem $item, $user_guid=0)
Can a user delete this river item?
$user_guid
Definition: login_as.php:10
Exception thrown if an argument is not of the expected type.
$params
Saves global plugin settings.
Definition: save.php:13
elgg_deprecated_notice(string $msg, string $dep_version)
Log a notice about deprecated use of a function, view, etc.
Definition: deprecation.php:52
if($id< 1) $annotation
Definition: delete.php:11
$type
Definition: delete.php:21
canAnnotate(ElggEntity $entity, $user_guid=0, $annotation_name= '')
Can a user annotate an entity?
__construct(PluginHooksService $hooks, EntityTable $entities, ElggSession $session)
Constructor.
canEdit($user_guid=0)
Can a user edit this entity?
canWriteToContainer(ElggEntity $entity, string $type, string $subtype, int $user_guid=0)
Can a user add an entity to this container.
canDownload(ElggFile $entity, $user_guid=0, $default=true)
Can a user download a file?
$entity
Definition: reset.php:8
canDelete(ElggEntity $entity, $user_guid=0)
Can a user delete this entity?
Exception indicating a user could not be looked up for a permissions check.
$user
Definition: ban.php:7
$container
Definition: delete.php:23
elgg ElggEntity
Definition: deprecated.js:437
if(isset($_COOKIE['elggperm'])) $session
Definition: login_as.php:28
canComment(ElggEntity $entity, $user_guid=0, $default=null)
Can a user comment on an entity?
canEditAnnotation(ElggEntity $entity, $user_guid=0, ElggAnnotation $annotation=null)
Determines whether or not the user can edit this annotation.
if($item instanceof\ElggEntity) elseif($item instanceof\ElggRiverItem) elseif($item instanceof ElggRelationship) elseif(is_callable([$item, 'getType']))
Definition: item.php:48
getType()
Returns the entity type.
$subtype
Definition: delete.php:22
getOriginalAttributes()
Get the original values of attribute(s) that have been modified since the entity was persisted...
Definition: ElggEntity.php:289
canEdit(ElggEntity $entity, $user_guid=0)
Can a user edit this entity?
canBypassPermissionsCheck($user_guid=0)
Decides if the access system should be ignored for a user.
User capabilities service.
if(empty($title)&&empty($body)) if(!empty($link)) $attrs
Definition: message.php:28
Entity table database service.
Definition: EntityTable.php:26