Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
AccessCollections.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg\Database;
4 
6 
20  private $site_guid;
21 
27  public function __construct($site_guid) {
28  $this->site_guid = $site_guid;
29  }
30 
46  function getAccessList($user_guid = 0, $site_guid = 0, $flush = false) {
47  global $init_finished;
48  $cache = _elgg_services()->accessCache;
49 
50  if ($flush) {
51  $cache->clear();
52  }
53 
54  if ($user_guid == 0) {
55  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
56  }
57 
58  if (($site_guid == 0) && $this->site_guid) {
59  $site_guid = $this->site_guid;
60  }
61  $user_guid = (int) $user_guid;
62  $site_guid = (int) $site_guid;
63 
64  $hash = $user_guid . $site_guid . 'get_access_list';
65 
66  if ($cache[$hash]) {
67  return $cache[$hash];
68  }
69 
70  $access_array = $this->getAccessArray($user_guid, $site_guid, $flush);
71  $access = "(" . implode(",", $access_array) . ")";
72 
73  if ($init_finished) {
74  $cache[$hash] = $access;
75  }
76 
77  return $access;
78  }
79 
105  function getAccessArray($user_guid = 0, $site_guid = 0, $flush = false) {
106  global $init_finished;
107 
108  $cache = _elgg_services()->accessCache;
109 
110  if ($flush) {
111  $cache->clear();
112  }
113 
114  if ($user_guid == 0) {
115  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
116  }
117 
118  if (($site_guid == 0) && $this->site_guid) {
119  $site_guid = $this->site_guid;
120  }
121 
122  $user_guid = (int) $user_guid;
123  $site_guid = (int) $site_guid;
124 
125  $hash = $user_guid . $site_guid . 'get_access_array';
126 
127  if ($cache[$hash]) {
128  $access_array = $cache[$hash];
129  } else {
130  $access_array = array(ACCESS_PUBLIC);
131 
132  // The following can only return sensible data for a known user.
133  if ($user_guid) {
134  $db = _elgg_services()->db;
135  $prefix = $db->getTablePrefix();
136 
137  $access_array[] = ACCESS_LOGGED_IN;
138 
139  // Get ACL memberships
140  $query = "SELECT am.access_collection_id"
141  . " FROM {$prefix}access_collection_membership am"
142  . " LEFT JOIN {$prefix}access_collections ag ON ag.id = am.access_collection_id"
143  . " WHERE am.user_guid = $user_guid AND (ag.site_guid = $site_guid OR ag.site_guid = 0)";
144 
145  $collections = $db->getData($query);
146  if ($collections) {
147  foreach ($collections as $collection) {
148  if (!empty($collection->access_collection_id)) {
149  $access_array[] = (int)$collection->access_collection_id;
150  }
151  }
152  }
153 
154  // Get ACLs owned.
155  $query = "SELECT ag.id FROM {$prefix}access_collections ag ";
156  $query .= "WHERE ag.owner_guid = $user_guid AND (ag.site_guid = $site_guid OR ag.site_guid = 0)";
157 
158  $collections = $db->getData($query);
159  if ($collections) {
160  foreach ($collections as $collection) {
161  if (!empty($collection->id)) {
162  $access_array[] = (int)$collection->id;
163  }
164  }
165  }
166 
167  $ignore_access = elgg_check_access_overrides($user_guid);
168 
169  if ($ignore_access == true) {
170  $access_array[] = ACCESS_PRIVATE;
171  }
172  }
173 
174  if ($init_finished) {
175  $cache[$hash] = $access_array;
176  }
177  }
178 
179  $options = array(
180  'user_id' => $user_guid,
181  'site_id' => $site_guid
182  );
183 
184  // see the warning in the docs for this function about infinite loop potential
185  return _elgg_services()->hooks->trigger('access:collections:read', 'user', $options, $access_array);
186  }
187 
227  function getWhereSql(array $options = array()) {
229 
230  $defaults = array(
231  'table_alias' => 'e',
232  'user_guid' => _elgg_services()->session->getLoggedInUserGuid(),
233  'use_enabled_clause' => !$ENTITY_SHOW_HIDDEN_OVERRIDE,
234  'access_column' => 'access_id',
235  'owner_guid_column' => 'owner_guid',
236  'guid_column' => 'guid',
237  );
238 
239  $options = array_merge($defaults, $options);
240 
241  // just in case someone passes a . at the end
242  $options['table_alias'] = rtrim($options['table_alias'], '.');
243 
244  foreach (array('table_alias', 'access_column', 'owner_guid_column', 'guid_column') as $key) {
245  $options[$key] = sanitize_string($options[$key]);
246  }
247  $options['user_guid'] = sanitize_int($options['user_guid'], false);
248 
249  // only add dot if we have an alias or table name
250  $table_alias = $options['table_alias'] ? $options['table_alias'] . '.' : '';
251 
252  $options['ignore_access'] = elgg_check_access_overrides($options['user_guid']);
253 
254  $clauses = array(
255  'ors' => array(),
256  'ands' => array()
257  );
258 
259  $prefix = _elgg_services()->db->getTablePrefix();
260 
261  if ($options['ignore_access']) {
262  $clauses['ors']['ignore_access'] = '1 = 1';
263  } else if ($options['user_guid']) {
264  // include content of user's friends
265  $clauses['ors']['friends_access'] = "$table_alias{$options['access_column']} = " . ACCESS_FRIENDS . "
266  AND $table_alias{$options['owner_guid_column']} IN (
267  SELECT guid_one FROM {$prefix}entity_relationships
268  WHERE relationship = 'friend' AND guid_two = {$options['user_guid']}
269  )";
270 
271  // include user's content
272  $clauses['ors']['owner_access'] = "$table_alias{$options['owner_guid_column']} = {$options['user_guid']}";
273  }
274 
275  // include standard accesses (public, logged in, access collections)
276  if (!$options['ignore_access']) {
277  $access_list = $this->getAccessList($options['user_guid']);
278  $clauses['ors']['acl_access'] = "$table_alias{$options['access_column']} IN {$access_list}";
279  }
280 
281  if ($options['use_enabled_clause']) {
282  $clauses['ands']['use_enabled'] = "{$table_alias}enabled = 'yes'";
283  }
284 
285  $clauses = _elgg_services()->hooks->trigger('get_sql', 'access', $options, $clauses);
286 
287  $clauses_str = '';
288  if (is_array($clauses['ors']) && $clauses['ors']) {
289  $clauses_str = '(' . implode(' OR ', $clauses['ors']) . ')';
290  }
291 
292  if (is_array($clauses['ands']) && $clauses['ands']) {
293  if ($clauses_str) {
294  $clauses_str .= ' AND ';
295  }
296  $clauses_str .= '(' . implode(' AND ', $clauses['ands']) . ')';
297  }
298 
299  return "($clauses_str)";
300  }
301 
321  function hasAccessToEntity($entity, $user = null) {
322  if (!$entity instanceof \ElggEntity) {
323  return false;
324  }
325 
326  // See #7159. Must not allow ignore access to affect query
327  $ia = elgg_set_ignore_access(false);
328 
329  if (!isset($user)) {
330  $access_bit = $this->getWhereSql();
331  } else {
332  $access_bit = $this->getWhereSql(array('user_guid' => $user->guid));
333  }
334 
336 
337  $db = _elgg_services()->db;
338  $prefix = $db->getTablePrefix();
339 
340  $query = "SELECT guid from {$prefix}entities e WHERE e.guid = {$entity->guid}";
341  // Add access controls
342  $query .= " AND " . $access_bit;
343  if ($db->getData($query)) {
344  return true;
345  } else {
346  return false;
347  }
348  }
349 
376  function getWriteAccessArray($user_guid = 0, $site_guid = 0, $flush = false, array $input_params = array()) {
377  global $init_finished;
378  $cache = _elgg_services()->accessCache;
379 
380  if ($flush) {
381  $cache->clear();
382  }
383 
384  if ($user_guid == 0) {
385  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
386  }
387 
388  if (($site_guid == 0) && $this->site_guid) {
389  $site_guid = $this->site_guid;
390  }
391 
392  $user_guid = (int) $user_guid;
393  $site_guid = (int) $site_guid;
394 
395  $hash = $user_guid . $site_guid . 'get_write_access_array';
396 
397  if ($cache[$hash]) {
398  $access_array = $cache[$hash];
399  } else {
400  // @todo is there such a thing as public write access?
401  $access_array = array(
406  );
407 
408  $collections = $this->getEntityCollections($user_guid, $site_guid);
409  if ($collections) {
410  foreach ($collections as $collection) {
411  $access_array[$collection->id] = $collection->name;
412  }
413  }
414 
415  if ($init_finished) {
416  $cache[$hash] = $access_array;
417  }
418  }
419 
420  $options = array(
421  'user_id' => $user_guid,
422  'site_id' => $site_guid,
423  'input_params' => $input_params,
424  );
425  return _elgg_services()->hooks->trigger('access:collections:write', 'user', $options, $access_array);
426  }
427 
442  function canEdit($collection_id, $user_guid = null) {
443  try {
444  $user = _elgg_services()->entityTable->getUserForPermissionsCheck($user_guid);
445  } catch (UserFetchFailureException $e) {
446  return false;
447  }
448 
449  $collection = $this->get($collection_id);
450 
451  if (!$user || !$collection) {
452  return false;
453  }
454 
455  $write_access = $this->getWriteAccessArray($user->guid, 0, true);
456 
457  // don't ignore access when checking users.
458  if ($user_guid) {
459  return array_key_exists($collection_id, $write_access);
460  } else {
461  return elgg_get_ignore_access() || array_key_exists($collection_id, $write_access);
462  }
463  }
464 
482  function create($name, $owner_guid = 0, $site_guid = 0) {
483  $name = trim($name);
484  if (empty($name)) {
485  return false;
486  }
487 
488  if ($owner_guid == 0) {
489  $owner_guid = _elgg_services()->session->getLoggedInUserGuid();
490  }
491  if (($site_guid == 0) && $this->site_guid) {
492  $site_guid = $this->site_guid;
493  }
494 
495  $db = _elgg_services()->db;
496  $prefix = $db->getTablePrefix();
497 
498  $name = $db->sanitizeString($name);
499 
500  $q = "INSERT INTO {$prefix}access_collections
501  SET name = '{$name}',
502  owner_guid = {$owner_guid},
503  site_guid = {$site_guid}";
504  $id = $db->insertData($q);
505  if (!$id) {
506  return false;
507  }
508 
509  $params = array(
510  'collection_id' => $id
511  );
512 
513  if (!_elgg_services()->hooks->trigger('access:collections:addcollection', 'collection', $params, true)) {
514  return false;
515  }
516 
517  return $id;
518  }
519 
535  $acl = $this->get($collection_id);
536 
537  if (!$acl) {
538  return false;
539  }
540  $members = (is_array($members)) ? $members : array();
541 
542  $cur_members = $this->getMembers($collection_id, true);
543  $cur_members = (is_array($cur_members)) ? $cur_members : array();
544 
545  $remove_members = array_diff($cur_members, $members);
546  $add_members = array_diff($members, $cur_members);
547 
548  $result = true;
549 
550  foreach ($add_members as $guid) {
551  $result = $result && $this->addUser($guid, $collection_id);
552  }
553 
554  foreach ($remove_members as $guid) {
555  $result = $result && $this->removeUser($guid, $collection_id);
556  }
557 
558  return $result;
559  }
560 
568  function delete($collection_id) {
570  $params = array('collection_id' => $collection_id);
571 
572  if (!_elgg_services()->hooks->trigger('access:collections:deletecollection', 'collection', $params, true)) {
573  return false;
574  }
575 
576  $db = _elgg_services()->db;
577  $prefix = $db->getTablePrefix();
578 
579  // Deleting membership doesn't affect result of deleting ACL.
580  $q = "DELETE FROM {$prefix}access_collection_membership
581  WHERE access_collection_id = {$collection_id}";
582  $db->deleteData($q);
583 
584  $q = "DELETE FROM {$prefix}access_collections
585  WHERE id = {$collection_id}";
586  $result = $db->deleteData($q);
587 
588  return (bool)$result;
589  }
590 
603  function get($collection_id) {
604 
606 
607  $db = _elgg_services()->db;
608  $prefix = $db->getTablePrefix();
609 
610  $query = "SELECT * FROM {$prefix}access_collections WHERE id = {$collection_id}";
611  $get_collection = $db->getDataRow($query);
612 
613  return $get_collection;
614  }
615 
628  $user_guid = (int) $user_guid;
630 
631  $collection = $this->get($collection_id);
632 
633  if (!($user instanceof \ElggUser) || !$collection) {
634  return false;
635  }
636 
637  $params = array(
638  'collection_id' => $collection_id,
639  'user_guid' => $user_guid
640  );
641 
642  $result = _elgg_services()->hooks->trigger('access:collections:add_user', 'collection', $params, true);
643  if ($result == false) {
644  return false;
645  }
646 
647  $db = _elgg_services()->db;
648  $prefix = $db->getTablePrefix();
649 
650  // if someone tries to insert the same data twice, we do a no-op on duplicate key
651  $q = "INSERT INTO {$prefix}access_collection_membership
652  SET access_collection_id = $collection_id, user_guid = $user_guid
653  ON DUPLICATE KEY UPDATE user_guid = user_guid";
654  $result = $db->insertData($q);
655 
656  return $result !== false;
657  }
658 
671  $user_guid = (int) $user_guid;
673 
674  $collection = $this->get($collection_id);
675 
676  if (!($user instanceof \ElggUser) || !$collection) {
677  return false;
678  }
679 
680  $params = array(
681  'collection_id' => $collection_id,
682  'user_guid' => $user_guid,
683  );
684 
685  if (!_elgg_services()->hooks->trigger('access:collections:remove_user', 'collection', $params, true)) {
686  return false;
687  }
688 
689  $db = _elgg_services()->db;
690  $prefix = $db->getTablePrefix();
691 
692  $q = "DELETE FROM {$prefix}access_collection_membership
693  WHERE access_collection_id = {$collection_id}
694  AND user_guid = {$user_guid}";
695 
696  return (bool)$db->deleteData($q);
697  }
698 
707  function getEntityCollections($owner_guid, $site_guid = 0) {
708  $owner_guid = (int) $owner_guid;
709  $site_guid = (int) $site_guid;
710 
711  if (($site_guid == 0) && $this->site_guid) {
712  $site_guid = $this->site_guid;
713  }
714 
715  $db = _elgg_services()->db;
716  $prefix = $db->getTablePrefix();
717 
718  $query = "SELECT * FROM {$prefix}access_collections
719  WHERE owner_guid = {$owner_guid}
720  AND site_guid = {$site_guid}
721  ORDER BY name ASC";
722 
723  $collections = $db->getData($query);
724 
725  return $collections;
726  }
727 
736  function getMembers($collection_id, $guids_only = false) {
738 
739  $db = _elgg_services()->db;
740  $prefix = $db->getTablePrefix();
741 
742  if (!$guids_only) {
743  $query = "SELECT e.* FROM {$prefix}access_collection_membership m"
744  . " JOIN {$prefix}entities e ON e.guid = m.user_guid"
745  . " WHERE m.access_collection_id = {$collection_id}";
746  $collection_members = $db->getData($query, "entity_row_to_elggstar");
747  } else {
748  $query = "SELECT e.guid FROM {$prefix}access_collection_membership m"
749  . " JOIN {$prefix}entities e ON e.guid = m.user_guid"
750  . " WHERE m.access_collection_id = {$collection_id}";
751  $collection_members = $db->getData($query);
752  if (!$collection_members) {
753  return false;
754  }
755  foreach ($collection_members as $key => $val) {
756  $collection_members[$key] = $val->guid;
757  }
758  }
759 
760  return $collection_members;
761  }
762 
771  function getCollectionsByMember($member_guid, $site_guid = 0) {
772  $member_guid = (int) $member_guid;
773  $site_guid = (int) $site_guid;
774 
775  if (($site_guid == 0) && $this->site_guid) {
776  $site_guid = $this->site_guid;
777  }
778 
779  $db = _elgg_services()->db;
780  $prefix = $db->getTablePrefix();
781 
782  $query = "SELECT ac.* FROM {$prefix}access_collections ac
783  JOIN {$prefix}access_collection_membership m ON ac.id = m.access_collection_id
784  WHERE m.user_guid = {$member_guid}
785  AND ac.site_guid = {$site_guid}
786  ORDER BY name ASC";
787 
788  $collections = $db->getData($query);
789 
790  return $collections;
791  }
792 
810  function getReadableAccessLevel($entity_access_id) {
811  $access = (int) $entity_access_id;
812 
813  $translator = _elgg_services()->translator;
814 
815  // Check if entity access id is a defined global constant
816  $access_array = array(
817  ACCESS_PRIVATE => $translator->translate("PRIVATE"),
818  ACCESS_FRIENDS => $translator->translate("access:friends:label"),
819  ACCESS_LOGGED_IN => $translator->translate("LOGGED_IN"),
820  ACCESS_PUBLIC => $translator->translate("PUBLIC"),
821  );
822 
823  if (array_key_exists($access, $access_array)) {
824  return $access_array[$access];
825  }
826 
827  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
828  if (!$user_guid) {
829  // return 'Limited' if there is no logged in user
830  return $translator->translate('access:limited:label');
831  }
832 
833  // Entity access id is probably a custom access collection
834  // Check if the user has write access to it and can see it's label
835  // Admins should always be able to see the readable version
836  $collection = $this->get($access);
837 
838  if ($collection) {
839  if (($collection->owner_guid == $user_guid) || _elgg_services()->session->isAdminLoggedIn()) {
840  return $collection->name;
841  }
842  }
843 
844  // return 'Limited' if the user does not have access to the access collection
845  return $translator->translate('access:limited:label');
846  }
847 }
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.
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
getMembers($collection_id, $guids_only=false)
Get all of members of an access collection.
$e
Definition: metadata.php:12
$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:65
$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.
$guid
Removes an admin notice.
const ACCESS_FRIENDS
Definition: elgglib.php:1991
$collection
getWhereSql(array $options=array())
Returns the SQL where clause for enforcing read access to data.
sanitize_string($string)
Sanitizes a string for use in a query.
Definition: database.php:153
$options
Elgg admin footer.
Definition: footer.php:6
elgg_get_ignore_access()
Get current ignore access setting.
Definition: access.php:54
$params
Definition: login.php:72
$owner_guid
addUser($user_guid, $collection_id)
Adds a user to an access collection.
$init_finished
A flag to set if Elgg's access initialization is finished.
Definition: access.php:521
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:503
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's access system should be ignored.
Definition: access.php:43
$ENTITY_SHOW_HIDDEN_OVERRIDE
Allow disabled entities and metadata to be returned by getter functions.
Definition: access.php:150
Exception indicating a user could not be looked up for a permissions check.
$user
Definition: ban.php:13
const ACCESS_PRIVATE
Definition: elgglib.php:1988
create($name, $owner_guid=0, $site_guid=0)
Creates a new access collection.
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
$collection_id
Definition: delete.php:9
const ACCESS_PUBLIC
Definition: elgglib.php:1990
getReadableAccessLevel($entity_access_id)
Return the name of an ACCESS_* constant or an access collection, but only if the logged in user owns ...
$entity
Definition: delete.php:7
const ACCESS_LOGGED_IN
Definition: elgglib.php:1989
sanitize_int($int, $signed=true)
Sanitizes an integer for database use.
Definition: database.php:180
$user_guid
Avatar remove action.
Definition: remove.php:6
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