Elgg  Version 1.11
AccessCollections.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Database;
4 
18  private $site_guid;
19 
25  public function __construct($site_guid) {
26  $this->site_guid = $site_guid;
27  }
28 
44  function getAccessList($user_guid = 0, $site_guid = 0, $flush = false) {
46  $cache = _elgg_services()->accessCache;
47 
48  if ($flush) {
49  $cache->clear();
50  }
51 
52  if ($user_guid == 0) {
53  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
54  }
55 
56  if (($site_guid == 0) && $this->site_guid) {
57  $site_guid = $this->site_guid;
58  }
59  $user_guid = (int) $user_guid;
60  $site_guid = (int) $site_guid;
61 
62  $hash = $user_guid . $site_guid . 'get_access_list';
63 
64  if ($cache[$hash]) {
65  return $cache[$hash];
66  }
67 
68  $access_array = get_access_array($user_guid, $site_guid, $flush);
69  $access = "(" . implode(",", $access_array) . ")";
70 
71  if ($init_finished) {
72  $cache[$hash] = $access;
73  }
74 
75  return $access;
76  }
77 
103  function getAccessArray($user_guid = 0, $site_guid = 0, $flush = false) {
105 
106  $cache = _elgg_services()->accessCache;
107 
108  if ($flush) {
109  $cache->clear();
110  }
111 
112  if ($user_guid == 0) {
113  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
114  }
115 
116  if (($site_guid == 0) && $this->site_guid) {
117  $site_guid = $this->site_guid;
118  }
119 
120  $user_guid = (int) $user_guid;
121  $site_guid = (int) $site_guid;
122 
123  $hash = $user_guid . $site_guid . 'get_access_array';
124 
125  if ($cache[$hash]) {
126  $access_array = $cache[$hash];
127  } else {
128  $access_array = array(ACCESS_PUBLIC);
129 
130  // The following can only return sensible data for a known user.
131  if ($user_guid) {
132  $db = _elgg_services()->db;
133  $prefix = $db->getTablePrefix();
134 
135  $access_array[] = ACCESS_LOGGED_IN;
136 
137  // Get ACL memberships
138  $query = "SELECT am.access_collection_id"
139  . " FROM {$prefix}access_collection_membership am"
140  . " LEFT JOIN {$prefix}access_collections ag ON ag.id = am.access_collection_id"
141  . " WHERE am.user_guid = $user_guid AND (ag.site_guid = $site_guid OR ag.site_guid = 0)";
142 
143  $collections = $db->getData($query);
144  if ($collections) {
145  foreach ($collections as $collection) {
146  if (!empty($collection->access_collection_id)) {
147  $access_array[] = (int)$collection->access_collection_id;
148  }
149  }
150  }
151 
152  // Get ACLs owned.
153  $query = "SELECT ag.id FROM {$prefix}access_collections ag ";
154  $query .= "WHERE ag.owner_guid = $user_guid AND (ag.site_guid = $site_guid OR ag.site_guid = 0)";
155 
156  $collections = $db->getData($query);
157  if ($collections) {
158  foreach ($collections as $collection) {
159  if (!empty($collection->id)) {
160  $access_array[] = (int)$collection->id;
161  }
162  }
163  }
164 
165  $ignore_access = elgg_check_access_overrides($user_guid);
166 
167  if ($ignore_access == true) {
168  $access_array[] = ACCESS_PRIVATE;
169  }
170  }
171 
172  if ($init_finished) {
173  $cache[$hash] = $access_array;
174  }
175  }
176 
177  $options = array(
178  'user_id' => $user_guid,
179  'site_id' => $site_guid
180  );
181 
182  // see the warning in the docs for this function about infinite loop potential
183  return _elgg_services()->hooks->trigger('access:collections:read', 'user', $options, $access_array);
184  }
185 
225  function getWhereSql(array $options = array()) {
227 
228  $defaults = array(
229  'table_alias' => 'e',
230  'user_guid' => _elgg_services()->session->getLoggedInUserGuid(),
231  'use_enabled_clause' => !$ENTITY_SHOW_HIDDEN_OVERRIDE,
232  'access_column' => 'access_id',
233  'owner_guid_column' => 'owner_guid',
234  'guid_column' => 'guid',
235  );
236 
237  $options = array_merge($defaults, $options);
238 
239  // just in case someone passes a . at the end
240  $options['table_alias'] = rtrim($options['table_alias'], '.');
241 
242  foreach (array('table_alias', 'access_column', 'owner_guid_column', 'guid_column') as $key) {
243  $options[$key] = sanitize_string($options[$key]);
244  }
245  $options['user_guid'] = sanitize_int($options['user_guid'], false);
246 
247  // only add dot if we have an alias or table name
248  $table_alias = $options['table_alias'] ? $options['table_alias'] . '.' : '';
249 
250  $options['ignore_access'] = elgg_check_access_overrides($options['user_guid']);
251 
252  $clauses = array(
253  'ors' => array(),
254  'ands' => array()
255  );
256 
257  $prefix = _elgg_services()->db->getTablePrefix();
258 
259  if ($options['ignore_access']) {
260  $clauses['ors'][] = '1 = 1';
261  } else if ($options['user_guid']) {
262  // include content of user's friends
263  $clauses['ors'][] = "$table_alias{$options['access_column']} = " . ACCESS_FRIENDS . "
264  AND $table_alias{$options['owner_guid_column']} IN (
265  SELECT guid_one FROM {$prefix}entity_relationships
266  WHERE relationship = 'friend' AND guid_two = {$options['user_guid']}
267  )";
268 
269  // include user's content
270  $clauses['ors'][] = "$table_alias{$options['owner_guid_column']} = {$options['user_guid']}";
271  }
272 
273  // include standard accesses (public, logged in, access collections)
274  if (!$options['ignore_access']) {
275  $access_list = get_access_list($options['user_guid']);
276  $clauses['ors'][] = "$table_alias{$options['access_column']} IN {$access_list}";
277  }
278 
279  if ($options['use_enabled_clause']) {
280  $clauses['ands'][] = "{$table_alias}enabled = 'yes'";
281  }
282 
283  $clauses = _elgg_services()->hooks->trigger('get_sql', 'access', $options, $clauses);
284 
285  $clauses_str = '';
286  if (is_array($clauses['ors']) && $clauses['ors']) {
287  $clauses_str = '(' . implode(' OR ', $clauses['ors']) . ')';
288  }
289 
290  if (is_array($clauses['ands']) && $clauses['ands']) {
291  if ($clauses_str) {
292  $clauses_str .= ' AND ';
293  }
294  $clauses_str .= '(' . implode(' AND ', $clauses['ands']) . ')';
295  }
296 
297  return "($clauses_str)";
298  }
299 
319  function hasAccessToEntity($entity, $user = null) {
320 
321 
322  // See #7159. Must not allow ignore access to affect query
323  $ia = elgg_set_ignore_access(false);
324 
325  if (!isset($user)) {
326  $access_bit = _elgg_get_access_where_sql();
327  } else {
328  $access_bit = _elgg_get_access_where_sql(array('user_guid' => $user->getGUID()));
329  }
330 
332 
333  $db = _elgg_services()->db;
334  $prefix = $db->getTablePrefix();
335 
336  $query = "SELECT guid from {$prefix}entities e WHERE e.guid = {$entity->guid}";
337  // Add access controls
338  $query .= " AND " . $access_bit;
339  if ($db->getData($query)) {
340  return true;
341  } else {
342  return false;
343  }
344  }
345 
372  function getWriteAccessArray($user_guid = 0, $site_guid = 0, $flush = false, array $input_params = array()) {
374  $cache = _elgg_services()->accessCache;
375 
376  if ($flush) {
377  $cache->clear();
378  }
379 
380  if ($user_guid == 0) {
381  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
382  }
383 
384  if (($site_guid == 0) && $this->site_guid) {
385  $site_guid = $this->site_guid;
386  }
387 
388  $user_guid = (int) $user_guid;
389  $site_guid = (int) $site_guid;
390 
391  $hash = $user_guid . $site_guid . 'get_write_access_array';
392 
393  if ($cache[$hash]) {
394  $access_array = $cache[$hash];
395  } else {
396  // @todo is there such a thing as public write access?
397  $access_array = array(
402  );
403 
404  $collections = $this->getEntityCollections($user_guid, $site_guid);
405  if ($collections) {
406  foreach ($collections as $collection) {
407  $access_array[$collection->id] = $collection->name;
408  }
409  }
410 
411  if ($init_finished) {
412  $cache[$hash] = $access_array;
413  }
414  }
415 
416  $options = array(
417  'user_id' => $user_guid,
418  'site_id' => $site_guid,
419  'input_params' => $input_params,
420  );
421  return _elgg_services()->hooks->trigger('access:collections:write', 'user', $options, $access_array);
422  }
423 
438  function canEdit($collection_id, $user_guid = null) {
439  if ($user_guid) {
440  $user = _elgg_services()->entityTable->get((int) $user_guid);
441  } else {
442  $user = _elgg_services()->session->getLoggedInUser();
443  }
444 
446 
447  if (!($user instanceof \ElggUser) || !$collection) {
448  return false;
449  }
450 
451  $write_access = get_write_access_array($user->getGUID(), 0, true);
452 
453  // don't ignore access when checking users.
454  if ($user_guid) {
455  return array_key_exists($collection_id, $write_access);
456  } else {
457  return elgg_get_ignore_access() || array_key_exists($collection_id, $write_access);
458  }
459  }
460 
478  function create($name, $owner_guid = 0, $site_guid = 0) {
479  $name = trim($name);
480  if (empty($name)) {
481  return false;
482  }
483 
484  if ($owner_guid == 0) {
485  $owner_guid = _elgg_services()->session->getLoggedInUserGuid();
486  }
487  if (($site_guid == 0) && $this->site_guid) {
488  $site_guid = $this->site_guid;
489  }
490 
491  $db = _elgg_services()->db;
492  $prefix = $db->getTablePrefix();
493 
494  $name = $db->sanitizeString($name);
495 
496  $q = "INSERT INTO {$prefix}access_collections
497  SET name = '{$name}',
498  owner_guid = {$owner_guid},
499  site_guid = {$site_guid}";
500  $id = $db->insertData($q);
501  if (!$id) {
502  return false;
503  }
504 
505  $params = array(
506  'collection_id' => $id
507  );
508 
509  if (!_elgg_services()->hooks->trigger('access:collections:addcollection', 'collection', $params, true)) {
510  return false;
511  }
512 
513  return $id;
514  }
515 
531  $acl = $this->get($collection_id);
532 
533  if (!$acl) {
534  return false;
535  }
536  $members = (is_array($members)) ? $members : array();
537 
538  $cur_members = $this->getMembers($collection_id, true);
539  $cur_members = (is_array($cur_members)) ? $cur_members : array();
540 
541  $remove_members = array_diff($cur_members, $members);
542  $add_members = array_diff($members, $cur_members);
543 
544  $result = true;
545 
546  foreach ($add_members as $guid) {
547  $result = $result && $this->addUser($guid, $collection_id);
548  }
549 
550  foreach ($remove_members as $guid) {
551  $result = $result && $this->removeUser($guid, $collection_id);
552  }
553 
554  return $result;
555  }
556 
564  function delete($collection_id) {
566  $params = array('collection_id' => $collection_id);
567 
568  if (!_elgg_services()->hooks->trigger('access:collections:deletecollection', 'collection', $params, true)) {
569  return false;
570  }
571 
572  $db = _elgg_services()->db;
573  $prefix = $db->getTablePrefix();
574 
575  // Deleting membership doesn't affect result of deleting ACL.
576  $q = "DELETE FROM {$prefix}access_collection_membership
577  WHERE access_collection_id = {$collection_id}";
578  $db->deleteData($q);
579 
580  $q = "DELETE FROM {$prefix}access_collections
581  WHERE id = {$collection_id}";
582  $result = $db->deleteData($q);
583 
584  return (bool)$result;
585  }
586 
599  function get($collection_id) {
600 
602 
603  $db = _elgg_services()->db;
604  $prefix = $db->getTablePrefix();
605 
606  $query = "SELECT * FROM {$prefix}access_collections WHERE id = {$collection_id}";
607  $get_collection = $db->getDataRow($query);
608 
609  return $get_collection;
610  }
611 
624  $user_guid = (int) $user_guid;
626 
627  $collection = $this->get($collection_id);
628 
629  if (!($user instanceof \ElggUser) || !$collection) {
630  return false;
631  }
632 
633  $params = array(
634  'collection_id' => $collection_id,
635  'user_guid' => $user_guid
636  );
637 
638  $result = _elgg_services()->hooks->trigger('access:collections:add_user', 'collection', $params, true);
639  if ($result == false) {
640  return false;
641  }
642 
643  $db = _elgg_services()->db;
644  $prefix = $db->getTablePrefix();
645 
646  // if someone tries to insert the same data twice, we do a no-op on duplicate key
647  $q = "INSERT INTO {$prefix}access_collection_membership
648  SET access_collection_id = $collection_id, user_guid = $user_guid
649  ON DUPLICATE KEY UPDATE user_guid = user_guid";
650  $result = $db->insertData($q);
651 
652  return $result !== false;
653  }
654 
667  $user_guid = (int) $user_guid;
669 
670  $collection = $this->get($collection_id);
671 
672  if (!($user instanceof \ElggUser) || !$collection) {
673  return false;
674  }
675 
676  $params = array(
677  'collection_id' => $collection_id,
678  'user_guid' => $user_guid,
679  );
680 
681  if (!_elgg_services()->hooks->trigger('access:collections:remove_user', 'collection', $params, true)) {
682  return false;
683  }
684 
685  $db = _elgg_services()->db;
686  $prefix = $db->getTablePrefix();
687 
688  $q = "DELETE FROM {$prefix}access_collection_membership
689  WHERE access_collection_id = {$collection_id}
690  AND user_guid = {$user_guid}";
691 
692  return (bool)$db->deleteData($q);
693  }
694 
703  function getEntityCollections($owner_guid, $site_guid = 0) {
704  $owner_guid = (int) $owner_guid;
705  $site_guid = (int) $site_guid;
706 
707  if (($site_guid == 0) && $this->site_guid) {
708  $site_guid = $this->site_guid;
709  }
710 
711  $db = _elgg_services()->db;
712  $prefix = $db->getTablePrefix();
713 
714  $query = "SELECT * FROM {$prefix}access_collections
715  WHERE owner_guid = {$owner_guid}
716  AND site_guid = {$site_guid}
717  ORDER BY name ASC";
718 
719  $collections = $db->getData($query);
720 
721  return $collections;
722  }
723 
732  function getMembers($collection, $idonly = false) {
733  $collection = (int)$collection;
734 
735  $db = _elgg_services()->db;
736  $prefix = $db->getTablePrefix();
737 
738  if (!$idonly) {
739  $query = "SELECT e.* FROM {$prefix}access_collection_membership m"
740  . " JOIN {$prefix}entities e ON e.guid = m.user_guid"
741  . " WHERE m.access_collection_id = {$collection}";
742  $collection_members = $db->getData($query, "entity_row_to_elggstar");
743  } else {
744  $query = "SELECT e.guid FROM {$prefix}access_collection_membership m"
745  . " JOIN {$prefix}entities e ON e.guid = m.user_guid"
746  . " WHERE m.access_collection_id = {$collection}";
747  $collection_members = $db->getData($query);
748  if (!$collection_members) {
749  return false;
750  }
751  foreach ($collection_members as $key => $val) {
752  $collection_members[$key] = $val->guid;
753  }
754  }
755 
756  return $collection_members;
757  }
758 
767  function getCollectionsByMember($member_guid, $site_guid = 0) {
768  $member_guid = (int) $member_guid;
769  $site_guid = (int) $site_guid;
770 
771  if (($site_guid == 0) && $this->site_guid) {
772  $site_guid = $this->site_guid;
773  }
774 
775  $db = _elgg_services()->db;
776  $prefix = $db->getTablePrefix();
777 
778  $query = "SELECT ac.* FROM {$prefix}access_collections ac
779  JOIN {$prefix}access_collection_membership m ON ac.id = m.access_collection_id
780  WHERE m.user_guid = {$member_guid}
781  AND ac.site_guid = {$site_guid}
782  ORDER BY name ASC";
783 
784  $collections = $db->getData($query);
785 
786  return $collections;
787  }
788 
806  function getReadableAccessLevel($entity_access_id) {
807  $access = (int) $entity_access_id;
808 
809  $translator = _elgg_services()->translator;
810 
811  // Check if entity access id is a defined global constant
812  $access_array = array(
813  ACCESS_PRIVATE => $translator->translate("PRIVATE"),
814  ACCESS_FRIENDS => $translator->translate("access:friends:label"),
815  ACCESS_LOGGED_IN => $translator->translate("LOGGED_IN"),
816  ACCESS_PUBLIC => $translator->translate("PUBLIC"),
817  );
818 
819  if (array_key_exists($access, $access_array)) {
820  return $access_array[$access];
821  }
822 
823  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
824  if (!$user_guid) {
825  // return 'Limited' if there is no logged in user
826  return $translator->translate('access:limited:label');
827  }
828 
829  // Entity access id is probably a custom access collection
830  // Check if the user has write access to it and can see it's label
831  // Admins should always be able to see the readable version
832  $collection = $this->get($access);
833 
834  if ($collection) {
835  if (($collection->owner_guid == $user_guid) || _elgg_services()->session->isAdminLoggedIn()) {
836  return $collection->name;
837  }
838  }
839 
840  // return 'Limited' if the user does not have access to the access collection
841  return $translator->translate('access:limited:label');
842  }
843 }
getAccessList($user_guid=0, $site_guid=0, $flush=false)
Return a string of access_ids for $user_guid appropriate for inserting into an SQL IN clause...
getCollectionsByMember($member_guid, $site_guid=0)
Return an array of database row objects of the access collections $entity_guid is a member of...
__construct($site_guid)
Constructor.
removeUser($user_guid, $collection_id)
Removes a user from an access collection.
get_access_array($user_guid=0, $site_guid=0, $flush=false)
Returns an array of access IDs a user is permitted to see.
Definition: access.php:102
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
$members
getWriteAccessArray($user_guid=0, $site_guid=0, $flush=false, array $input_params=array())
Returns an array of access permissions that the user is allowed to save content with.
$CONFIG site_guid
The guid of the current site object.
Definition: config.php:122
$defaults
hasAccessToEntity($entity, $user=null)
Can a user access an entity.
update($collection_id, $members)
Updates the membership in an access collection.
getAccessArray($user_guid=0, $site_guid=0, $flush=false)
Returns an array of access IDs a user is permitted to see.
$ia
Definition: upgrade.php:26
$guid
Removes an admin notice.
const ACCESS_FRIENDS
Definition: elgglib.php:1957
$collection
getWhereSql(array $options=array())
Returns the SQL where clause for enforcing read access to data.
get_access_collection($collection_id)
Get a specified access collection.
Definition: access.php:359
sanitize_string($string)
Sanitize a string for database use.
Definition: database.php:140
elgg_get_ignore_access()
Get current ignore access setting.
Definition: access.php:54
$params
Definition: login.php:72
$options
Definition: index.php:14
$owner_guid
addUser($user_guid, $collection_id)
Adds a user to an access collection.
$init_finished
A flag to set if Elgg&#39;s access initialization is finished.
Definition: access.php:523
getEntityCollections($owner_guid, $site_guid=0)
Returns an array of database row objects of the access collections owned by $owner_guid.
elgg_check_access_overrides($user_guid=0)
Decides if the access system should be ignored for a user.
Definition: access.php:505
get_user($guid)
Get a user object from a GUID.
Definition: users.php:87
$key
Definition: summary.php:34
elgg_set_ignore_access($ignore=true)
Set if Elgg&#39;s access system should be ignored.
Definition: access.php:43
get_write_access_array($user_guid=0, $site_guid=0, $flush=false, array $input_params=array())
Returns an array of access permissions that the user is allowed to save content with.
Definition: access.php:269
_elgg_services()
Definition: autoloader.php:14
getMembers($collection, $idonly=false)
Get all of members of an access collection.
$ENTITY_SHOW_HIDDEN_OVERRIDE
Allow disabled entities and metadata to be returned by getter functions.
Definition: access.php:150
$user
Definition: ban.php:13
const ACCESS_PRIVATE
Definition: elgglib.php:1954
elgg global
Pointer to the global context.
Definition: elgglib.js:12
get_access_list($user_guid=0, $site_guid=0, $flush=false)
Return a string of access_ids for $user_guid appropriate for inserting into an SQL IN clause...
Definition: access.php:73
create($name, $owner_guid=0, $site_guid=0)
Creates a new access collection.
$collection_id
Definition: delete.php:9
const ACCESS_PUBLIC
Definition: elgglib.php:1956
getReadableAccessLevel($entity_access_id)
Return the name of an ACCESS_* constant or an access collection, but only if the logged in user owns ...
const ACCESS_LOGGED_IN
Definition: elgglib.php:1955
sanitize_int($int, $signed=true)
Sanitizes an integer for database use.
Definition: database.php:161
$user_guid
Avatar remove action.
Definition: remove.php:6
$entity
Definition: delete.php:10
_elgg_get_access_where_sql(array $options=array())
Returns the SQL where clause for enforcing read access to data.
Definition: access.php:216
if(!$collection_name) $id
Definition: add.php:17
canEdit($collection_id, $user_guid=null)
Can the user change this access collection?
$access
Definition: save.php:15