Elgg  Version 1.12
ElggEntity.php
Go to the documentation of this file.
1 <?php
41 abstract class ElggEntity extends \ElggData implements
42  Notable, // Calendar interface (deprecated 1.9)
43  Locatable, // Geocoding interface
44  Importable // Allow import of data (deprecated 1.9)
45 {
46 
50  protected $url_override;
51 
55  protected $icon_override;
56 
61  protected $temp_metadata = array();
62 
67  protected $temp_annotations = array();
68 
73  protected $temp_private_settings = array();
74 
79  protected $volatile = array();
80 
86  protected $tables_split;
87 
93  protected $tables_loaded;
94 
102  protected function initializeAttributes() {
103  parent::initializeAttributes();
104 
105  $this->attributes['guid'] = null;
106  $this->attributes['type'] = null;
107  $this->attributes['subtype'] = null;
108 
109  $this->attributes['owner_guid'] = _elgg_services()->session->getLoggedInUserGuid();
110  $this->attributes['container_guid'] = _elgg_services()->session->getLoggedInUserGuid();
111 
112  $this->attributes['site_guid'] = null;
113  $this->attributes['access_id'] = ACCESS_PRIVATE;
114  $this->attributes['time_updated'] = null;
115  $this->attributes['last_action'] = null;
116  $this->attributes['enabled'] = "yes";
117 
118  // There now follows a bit of a hack
119  /* Problem: To speed things up, some objects are split over several tables,
120  * this means that it requires n number of database reads to fully populate
121  * an entity. This causes problems for caching and create events
122  * since it is not possible to tell whether a subclassed entity is complete.
123  *
124  * Solution: We have two counters, one 'tables_split' which tells whatever is
125  * interested how many tables are going to need to be searched in order to fully
126  * populate this object, and 'tables_loaded' which is how many have been
127  * loaded thus far.
128  *
129  * If the two are the same then this object is complete.
130  *
131  * Use: isFullyLoaded() to check
132  */
133  $this->tables_split = 1;
134  $this->tables_loaded = 0;
135  }
136 
150  public function __clone() {
151  $orig_entity = get_entity($this->guid);
152  if (!$orig_entity) {
153  _elgg_services()->logger->error("Failed to clone entity with GUID $this->guid");
154  return;
155  }
156 
157  $metadata_array = elgg_get_metadata(array(
158  'guid' => $this->guid,
159  'limit' => 0
160  ));
161 
162  $this->attributes['guid'] = "";
163 
164  $this->attributes['subtype'] = $orig_entity->getSubtype();
165 
166  // copy metadata over to new entity - slightly convoluted due to
167  // handling of metadata arrays
168  if (is_array($metadata_array)) {
169  // create list of metadata names
170  $metadata_names = array();
171  foreach ($metadata_array as $metadata) {
172  $metadata_names[] = $metadata['name'];
173  }
174  // arrays are stored with multiple enties per name
175  $metadata_names = array_unique($metadata_names);
176 
177  // move the metadata over
178  foreach ($metadata_names as $name) {
179  $this->__set($name, $orig_entity->$name);
180  }
181  }
182  }
183 
197  public function __set($name, $value) {
198  if ($this->$name === $value) {
199  // quick return if value is not changing
200  return;
201  }
202  if (array_key_exists($name, $this->attributes)) {
203  // Certain properties should not be manually changed!
204  switch ($name) {
205  case 'guid':
206  case 'time_updated':
207  case 'last_action':
208  return;
209  break;
210  case 'access_id':
211  case 'owner_guid':
212  case 'container_guid':
213  if ($value !== null) {
214  $this->attributes[$name] = (int)$value;
215  } else {
216  $this->attributes[$name] = null;
217  }
218  break;
219  default:
220  $this->attributes[$name] = $value;
221  break;
222  }
223  } else {
224  $this->setMetadata($name, $value);
225  }
226  }
227 
237  public function set($name, $value) {
238  elgg_deprecated_notice("Use -> instead of set()", 1.9);
239  $this->__set($name, $value);
240 
241  return true;
242  }
243 
256  public function __get($name) {
257  if (array_key_exists($name, $this->attributes)) {
258  if ($name === 'subtype' && $this->attributes['guid']) {
259  // note: only show deprecation notice if user reads ->subtype after save/load
260  elgg_deprecated_notice("Use getSubtype()", 1.9);
261  }
262  return $this->attributes[$name];
263  }
264 
265  return $this->getMetadata($name);
266  }
267 
275  public function get($name) {
276  elgg_deprecated_notice("Use -> instead of get()", 1.9);
277  return $this->__get($name);
278  }
279 
285  abstract public function getDisplayName();
286 
293  abstract public function setDisplayName($displayName);
294 
302  public function getMetadata($name) {
303  $guid = $this->getGUID();
304 
305  if (!$guid) {
306  if (isset($this->temp_metadata[$name])) {
307  // md is returned as an array only if more than 1 entry
308  if (count($this->temp_metadata[$name]) == 1) {
309  return $this->temp_metadata[$name][0];
310  } else {
311  return $this->temp_metadata[$name];
312  }
313  } else {
314  return null;
315  }
316  }
317 
318  // upon first cache miss, just load/cache all the metadata and retry.
319  // if this works, the rest of this function may not be needed!
320  $cache = _elgg_services()->metadataCache;
321  if ($cache->isLoaded($guid)) {
322  return $cache->getSingle($guid, $name);
323  } else {
324  $cache->populateFromEntities(array($guid));
325  // in case ignore_access was on, we have to check again...
326  if ($cache->isLoaded($guid)) {
327  return $cache->getSingle($guid, $name);
328  }
329  }
330 
331  $md = elgg_get_metadata(array(
332  'guid' => $guid,
333  'metadata_name' => $name,
334  'limit' => 0,
335  'distinct' => false,
336  ));
337 
338  $value = null;
339 
340  if ($md && !is_array($md)) {
341  $value = $md->value;
342  } elseif (count($md) == 1) {
343  $value = $md[0]->value;
344  } else if ($md && is_array($md)) {
346  }
347 
348  return $value;
349  }
350 
361  public function __unset($name) {
362  if (array_key_exists($name, $this->attributes)) {
363  $this->attributes[$name] = "";
364  } else {
365  $this->deleteMetadata($name);
366  }
367  }
368 
389  public function setMetadata($name, $value, $value_type = '', $multiple = false, $owner_guid = 0, $access_id = null) {
390 
391  // normalize value to an array that we will loop over
392  // remove indexes if value already an array.
393  if (is_array($value)) {
394  $value = array_values($value);
395  } else {
396  $value = array($value);
397  }
398 
399  // saved entity. persist md to db.
400  if ($this->guid) {
401  // if overwriting, delete first.
402  if (!$multiple) {
403  $options = array(
404  'guid' => $this->getGUID(),
405  'metadata_name' => $name,
406  'limit' => 0
407  );
408  // @todo in 1.9 make this return false if can't add metadata
409  // https://github.com/elgg/elgg/issues/4520
410  //
411  // need to remove access restrictions right now to delete
412  // because this is the expected behavior
413  $ia = elgg_set_ignore_access(true);
414  if (false === elgg_delete_metadata($options)) {
415  return false;
416  }
418  }
419 
420  $owner_guid = (int)$owner_guid;
421  $access_id = ($access_id === null) ? $this->getAccessId() : (int)$access_id;
423 
424  // add new md
425  $result = true;
426  foreach ($value as $value_tmp) {
427  // at this point $value is appended because it was cleared above if needed.
428  $md_id = create_metadata($this->getGUID(), $name, $value_tmp, $value_type,
429  $owner_guid, $access_id, true);
430  if (!$md_id) {
431  return false;
432  }
433  }
434 
435  return $result;
436  } else {
437  // unsaved entity. store in temp array
438 
439  // returning single entries instead of an array of 1 element is decided in
440  // getMetaData(), just like pulling from the db.
441 
442  if ($owner_guid != 0 || $access_id !== null) {
443  $msg = "owner guid and access id cannot be used in \ElggEntity::setMetadata() until entity is saved.";
444  throw new \InvalidArgumentException($msg);
445  }
446 
447  // if overwrite, delete first
448  if (!$multiple || !isset($this->temp_metadata[$name])) {
449  $this->temp_metadata[$name] = array();
450  }
451 
452  // add new md
453  $this->temp_metadata[$name] = array_merge($this->temp_metadata[$name], $value);
454  return true;
455  }
456  }
457 
468  public function deleteMetadata($name = null) {
469 
470  if (!$this->guid) {
471  return false;
472  }
473 
474  $options = array(
475  'guid' => $this->guid,
476  'limit' => 0
477  );
478  if ($name) {
479  $options['metadata_name'] = $name;
480  }
481 
483  }
484 
493  public function deleteOwnedMetadata($name = null) {
494  // access is turned off for this because they might
495  // no longer have access to an entity they created metadata on.
496  $ia = elgg_set_ignore_access(true);
497  $options = array(
498  'metadata_owner_guid' => $this->guid,
499  'limit' => 0
500  );
501  if ($name) {
502  $options['metadata_name'] = $name;
503  }
504 
507  return $r;
508  }
509 
519  public function clearMetadata($name = '') {
520  elgg_deprecated_notice('\ElggEntity->clearMetadata() is deprecated by ->deleteMetadata()', 1.8);
521  return $this->deleteMetadata($name);
522  }
523 
531  public function disableMetadata($name = '') {
532  $options = array(
533  'guid' => $this->guid,
534  'limit' => 0
535  );
536  if ($name) {
537  $options['metadata_name'] = $name;
538  }
539 
541  }
542 
552  public function enableMetadata($name = '') {
553  $options = array(
554  'guid' => $this->guid,
555  'limit' => 0
556  );
557  if ($name) {
558  $options['metadata_name'] = $name;
559  }
560 
562  }
563 
571  public function getVolatileData($name) {
572  if (!is_array($this->volatile)) {
573  $this->volatile = array();
574  }
575 
576  if (array_key_exists($name, $this->volatile)) {
577  return $this->volatile[$name];
578  } else {
579  return null;
580  }
581  }
582 
591  public function setVolatileData($name, $value) {
592  if (!is_array($this->volatile)) {
593  $this->volatile = array();
594  }
595 
596  $this->volatile[$name] = $value;
597  }
598 
612  public function deleteRelationships($relationship = null) {
613  $relationship = (string)$relationship;
614  $result = remove_entity_relationships($this->getGUID(), $relationship);
615  return $result && remove_entity_relationships($this->getGUID(), $relationship, true);
616  }
617 
626  public function clearRelationships() {
627  elgg_deprecated_notice('\ElggEntity->clearRelationships() is deprecated by ->deleteRelationships()', 1.8);
628  return $this->deleteRelationships();
629  }
630 
643  public function addRelationship($guid_two, $relationship) {
644  return add_entity_relationship($this->getGUID(), $relationship, $guid_two);
645  }
646 
657  public function removeRelationship($guid_two, $relationship) {
658  return remove_entity_relationship($this->getGUID(), $relationship, $guid_two);
659  }
660 
672  public function setPrivateSetting($name, $value) {
673  if ((int) $this->guid > 0) {
674  return set_private_setting($this->getGUID(), $name, $value);
675  } else {
676  $this->temp_private_settings[$name] = $value;
677  return true;
678  }
679  }
680 
688  public function getPrivateSetting($name) {
689  if ((int) ($this->guid) > 0) {
690  return get_private_setting($this->getGUID(), $name);
691  } else {
692  if (isset($this->temp_private_settings[$name])) {
693  return $this->temp_private_settings[$name];
694  }
695  }
696  return null;
697  }
698 
706  public function removePrivateSetting($name) {
707  return remove_private_setting($this->getGUID(), $name);
708  }
709 
720  public function deleteAnnotations($name = null) {
721  $options = array(
722  'guid' => $this->guid,
723  'limit' => 0
724  );
725  if ($name) {
726  $options['annotation_name'] = $name;
727  }
728 
730  }
731 
740  public function deleteOwnedAnnotations($name = null) {
741  // access is turned off for this because they might
742  // no longer have access to an entity they created annotations on.
743  $ia = elgg_set_ignore_access(true);
744  $options = array(
745  'annotation_owner_guid' => $this->guid,
746  'limit' => 0
747  );
748  if ($name) {
749  $options['annotation_name'] = $name;
750  }
751 
754  return $r;
755  }
756 
764  public function disableAnnotations($name = '') {
765  $options = array(
766  'guid' => $this->guid,
767  'limit' => 0
768  );
769  if ($name) {
770  $options['annotation_name'] = $name;
771  }
772 
774  }
775 
785  public function enableAnnotations($name = '') {
786  $options = array(
787  'guid' => $this->guid,
788  'limit' => 0
789  );
790  if ($name) {
791  $options['annotation_name'] = $name;
792  }
793 
795  }
796 
804  private function getAnnotationCalculation($name, $calculation) {
805  $options = array(
806  'guid' => $this->getGUID(),
807  'distinct' => false,
808  'annotation_name' => $name,
809  'annotation_calculation' => $calculation
810  );
811 
813  }
814 
831  public function annotate($name, $value, $access_id = ACCESS_PRIVATE, $owner_guid = 0, $vartype = "") {
832  if ((int) $this->guid > 0) {
833  return create_annotation($this->getGUID(), $name, $value, $vartype, $owner_guid, $access_id);
834  } else {
835  $this->temp_annotations[$name] = $value;
836  }
837  return true;
838  }
839 
855  public function getAnnotations($options = array(), $limit = 50, $offset = 0, $order = "asc") {
856  if (!is_array($options)) {
857  elgg_deprecated_notice("\ElggEntity::getAnnotations() takes an array of options.", 1.9);
858  }
859 
860  if ((int) ($this->guid) > 0) {
861  if (!is_array($options)) {
862  $options = array(
863  'guid' => $this->guid,
864  'annotation_name' => $options,
865  'limit' => $limit,
866  'offset' => $offset,
867  );
868 
869  if ($order != 'asc') {
870  $options['reverse_order_by'] = true;
871  }
872  } else {
873  $options['guid'] = $this->guid;
874  }
875 
877  } else {
878  if (!is_array($options)) {
879  $name = $options;
880  } else {
881  $name = elgg_extract('annotation_name', $options, '');
882  }
883 
884  if (isset($this->temp_annotations[$name])) {
885  return array($this->temp_annotations[$name]);
886  }
887  }
888 
889  return array();
890  }
891 
902  public function clearAnnotations($name = "") {
903  elgg_deprecated_notice('\ElggEntity->clearAnnotations() is deprecated by ->deleteAnnotations()', 1.8);
904  return $this->deleteAnnotations($name);
905  }
906 
914  public function countAnnotations($name = "") {
915  return $this->getAnnotationCalculation($name, 'count');
916  }
917 
925  public function getAnnotationsAvg($name) {
926  return $this->getAnnotationCalculation($name, 'avg');
927  }
928 
936  public function getAnnotationsSum($name) {
937  return $this->getAnnotationCalculation($name, 'sum');
938  }
939 
947  public function getAnnotationsMin($name) {
948  return $this->getAnnotationCalculation($name, 'min');
949  }
950 
958  public function getAnnotationsMax($name) {
959  return $this->getAnnotationCalculation($name, 'max');
960  }
961 
968  public function countComments() {
969  $params = array('entity' => $this);
970  $num = _elgg_services()->hooks->trigger('comments:count', $this->getType(), $params);
971 
972  if (is_int($num)) {
973  return $num;
974  } else {
975  return elgg_get_entities(array(
976  'type' => 'object',
977  'subtype' => 'comment',
978  'container_guid' => $this->getGUID(),
979  'count' => true,
980  'distinct' => false,
981  ));
982  }
983  }
984 
998  public function getEntitiesFromRelationship($options = array(), $inverse = false, $limit = 50, $offset = 0) {
999  if (is_array($options)) {
1000  $options['relationship_guid'] = $this->getGUID();
1002  } else {
1003  elgg_deprecated_notice("\ElggEntity::getEntitiesFromRelationship takes an options array", 1.9);
1005  'relationship' => $options,
1006  'relationship_guid' => $this->getGUID(),
1007  'inverse_relationship' => $inverse,
1008  'limit' => $limit,
1009  'offset' => $offset
1010  ));
1011  }
1012  }
1013 
1022  public function countEntitiesFromRelationship($relationship, $inverse_relationship = false) {
1024  'relationship' => $relationship,
1025  'relationship_guid' => $this->getGUID(),
1026  'inverse_relationship' => $inverse_relationship,
1027  'count' => true
1028  ));
1029  }
1030 
1041  public function canEdit($user_guid = 0) {
1042  $user_guid = (int)$user_guid;
1044  if (!$user) {
1045  $user = _elgg_services()->session->getLoggedInUser();
1046  }
1047 
1048  $return = false;
1049 
1050  // Test user if possible - should default to false unless a plugin hook says otherwise
1051  if ($user) {
1052  if ($this->getOwnerGUID() == $user->getGUID()) {
1053  $return = true;
1054  }
1055 
1056  if ($this->getContainerGUID() == $user->getGUID()) {
1057  $return = true;
1058  }
1059 
1060  if ($this->getGUID() == $user->getGUID()) {
1061  $return = true;
1062  }
1063 
1064  $container = $this->getContainerEntity();
1065  if ($container && $container->canEdit($user->getGUID())) {
1066  $return = true;
1067  }
1068  }
1069 
1070  $params = array('entity' => $this, 'user' => $user);
1071  return _elgg_services()->hooks->trigger('permissions_check', $this->type, $params, $return);
1072  }
1073 
1085  public function canDelete($user_guid = 0) {
1086  $user_guid = (int) $user_guid;
1087 
1088  if (!$user_guid) {
1089  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
1090  }
1091 
1092  // need to ignore access and show hidden entities for potential hidden/disabled users
1093  $ia = elgg_set_ignore_access(true);
1094  $show_hidden = access_show_hidden_entities(true);
1095 
1096  $user = _elgg_services()->entityTable->get($user_guid, 'user');
1097 
1099  access_show_hidden_entities($show_hidden);
1100 
1101  if ($user_guid & !$user) {
1102  // requested to check access for a specific user_guid, but there is no user entity, so return false
1103  $message = _elgg_services()->translator->translate('entity:can_delete:invaliduser', array($user_guid));
1104  _elgg_services()->logger->warning($message);
1105 
1106  return false;
1107  }
1108 
1109  $return = $this->canEdit($user_guid);
1110 
1111  $params = array('entity' => $this, 'user' => $user);
1112  return _elgg_services()->hooks->trigger('permissions_check:delete', $this->type, $params, $return);
1113  }
1114 
1130  public function canEditMetadata($metadata = null, $user_guid = 0) {
1131  if (!$this->guid) {
1132  // @todo cannot edit metadata on unsaved entity?
1133  return false;
1134  }
1135 
1136  if ($user_guid) {
1138  if (!$user) {
1139  return false;
1140  }
1141  } else {
1142  $user = _elgg_services()->session->getLoggedInUser();
1143  $user_guid = $user->guid;
1144  }
1145 
1146  $return = null;
1147 
1148  // if metadata is not owned or owned by the user, then can edit
1149  if ($metadata && ($metadata->owner_guid == 0 || $metadata->owner_guid == $user_guid)) {
1150  $return = true;
1151  }
1152 
1153  if (is_null($return)) {
1154  $return = $this->canEdit($user_guid);
1155  }
1156 
1157  // metadata and user may be null
1158  $params = array('entity' => $this, 'user' => $user, 'metadata' => $metadata);
1159  return _elgg_services()->hooks->trigger('permissions_check:metadata', $this->type, $params, $return);
1160  }
1161 
1172  public function canWriteToContainer($user_guid = 0, $type = 'all', $subtype = 'all') {
1173  return can_write_to_container($user_guid, $this->guid, $type, $subtype);
1174  }
1175 
1186  public function canComment($user_guid = 0) {
1187  if ($user_guid == 0) {
1188  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
1189  }
1191 
1192  // By default, we don't take a position of whether commenting is allowed
1193  // because it is handled by the subclasses of \ElggEntity
1194  $params = array('entity' => $this, 'user' => $user);
1195  return _elgg_services()->hooks->trigger('permissions_check:comment', $this->type, $params, null);
1196  }
1197 
1212  public function canAnnotate($user_guid = 0, $annotation_name = '') {
1213  if ($user_guid == 0) {
1214  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
1215  }
1217 
1218  $return = true;
1219  if (!$user) {
1220  $return = false;
1221  }
1222 
1223  $hooks = _elgg_services()->hooks;
1224 
1225  $params = array(
1226  'entity' => $this,
1227  'user' => $user,
1228  'annotation_name' => $annotation_name,
1229  );
1230  if ($annotation_name !== '') {
1231  $return = $hooks->trigger("permissions_check:annotate:$annotation_name", $this->type, $params, $return);
1232  }
1233  $return = $hooks->trigger('permissions_check:annotate', $this->type, $params, $return);
1234 
1235  return $return;
1236  }
1237 
1243  public function getAccessID() {
1244  return $this->access_id;
1245  }
1246 
1252  public function getGUID() {
1253  return $this->guid;
1254  }
1255 
1261  public function getType() {
1262  return $this->type;
1263  }
1264 
1270  public function getSubtype() {
1271  // If this object hasn't been saved, then return the subtype string.
1272  if ($this->attributes['guid']) {
1273  return get_subtype_from_id($this->attributes['subtype']);
1274  }
1275  return $this->attributes['subtype'];
1276  }
1277 
1283  public function getOwnerGUID() {
1284  return (int)$this->owner_guid;
1285  }
1286 
1293  public function getOwner() {
1294  elgg_deprecated_notice("\ElggEntity::getOwner deprecated for \ElggEntity::getOwnerGUID", 1.8);
1295  return $this->getOwnerGUID();
1296  }
1297 
1303  public function getOwnerEntity() {
1304  return get_entity($this->owner_guid);
1305  }
1306 
1315  return $this->container_guid = (int)$container_guid;
1316  }
1317 
1326  public function setContainer($container_guid) {
1327  elgg_deprecated_notice("\ElggObject::setContainer deprecated for \ElggEntity::setContainerGUID", 1.8);
1328  return $this->setContainerGUID('container_guid', $container_guid);
1329  }
1330 
1336  public function getContainerGUID() {
1337  return (int)$this->container_guid;
1338  }
1339 
1346  public function getContainer() {
1347  elgg_deprecated_notice("\ElggObject::getContainer deprecated for \ElggEntity::getContainerGUID", 1.8);
1348  return $this->getContainerGUID();
1349  }
1350 
1357  public function getContainerEntity() {
1358  return get_entity($this->getContainerGUID());
1359  }
1360 
1366  public function getTimeUpdated() {
1367  return $this->time_updated;
1368  }
1369 
1378  public function getURL() {
1379 
1380  $url = "";
1381 
1382  // @todo remove when elgg_register_entity_url_handler() has been removed
1383  if ($this->guid) {
1384  global $CONFIG;
1385  if (isset($CONFIG->entity_url_handler[$this->getType()][$this->getSubtype()])) {
1386  $function = $CONFIG->entity_url_handler[$this->getType()][$this->getSubtype()];
1387  if (is_callable($function)) {
1388  $url = call_user_func($function, $this);
1389  }
1390  } elseif (isset($CONFIG->entity_url_handler[$this->getType()]['all'])) {
1391  $function = $CONFIG->entity_url_handler[$this->getType()]['all'];
1392  if (is_callable($function)) {
1393  $url = call_user_func($function, $this);
1394  }
1395  } elseif (isset($CONFIG->entity_url_handler['all']['all'])) {
1396  $function = $CONFIG->entity_url_handler['all']['all'];
1397  if (is_callable($function)) {
1398  $url = call_user_func($function, $this);
1399  }
1400  }
1401 
1402  if ($url) {
1404  }
1405  }
1406 
1407  $type = $this->getType();
1408  $params = array('entity' => $this);
1409  $url = _elgg_services()->hooks->trigger('entity:url', $type, $params, $url);
1410 
1411  // @todo remove when \ElggEntity::setURL() has been removed
1412  if (!empty($this->url_override)) {
1414  }
1415 
1416  return elgg_normalize_url($url);
1417  }
1418 
1429  public function setURL($url) {
1430  elgg_deprecated_notice('\ElggEntity::setURL() has been replaced by the "entity:url" plugin hook', 1.9);
1431  $this->url_override = $url;
1432  return $url;
1433  }
1434 
1446  public function getIconURL($params = array()) {
1447  if (is_array($params)) {
1448  $size = elgg_extract('size', $params, 'medium');
1449  } else {
1450  $size = is_string($params) ? $params : 'medium';
1451  $params = array();
1452  }
1454 
1455  if (isset($this->icon_override[$size])) {
1456  elgg_deprecated_notice("icon_override on an individual entity is deprecated", 1.8);
1457  return $this->icon_override[$size];
1458  }
1459 
1460  $params['entity'] = $this;
1461  $params['size'] = $size;
1462 
1463  $type = $this->getType();
1464 
1465  $url = _elgg_services()->hooks->trigger('entity:icon:url', $type, $params, null);
1466  if ($url == null) {
1467  $url = "_graphics/icons/default/$size.png";
1468  }
1469 
1470  return elgg_normalize_url($url);
1471  }
1472 
1481  public function getIcon($size = 'medium') {
1482  elgg_deprecated_notice("getIcon() deprecated by getIconURL()", 1.8);
1483  return $this->getIconURL($size);
1484  }
1485 
1497  public function setIcon($url, $size = 'medium') {
1498  elgg_deprecated_notice("icon_override on an individual entity is deprecated", 1.8);
1499 
1502 
1503  if (!$this->icon_override) {
1504  $this->icon_override = array();
1505  }
1506  $this->icon_override[$size] = $url;
1507 
1508  return true;
1509  }
1510 
1522  public function addToSite($site) {
1523  if (!elgg_instanceof($site, 'site')) {
1524  return false;
1525  }
1526 
1527  return $site->addEntity($this);
1528  }
1529 
1540  public function removeFromSite($site) {
1541  if (!elgg_instanceof($site, 'site')) {
1542  return false;
1543  }
1544 
1545  return $site->removeEntity($this);
1546  }
1547 
1560  public function getSites($options = array()) {
1561  $options['relationship'] = 'member_of_site';
1562  $options['relationship_guid'] = $this->guid;
1563  $options['inverse_relationship'] = false;
1564  if (!isset($options['site_guid']) || !isset($options['site_guids'])) {
1565  $options['site_guids'] = ELGG_ENTITIES_ANY_VALUE;
1566  }
1567 
1569  }
1570 
1576  public function isFullyLoaded() {
1577  return ! ($this->tables_loaded < $this->tables_split);
1578  }
1579 
1587  public function save() {
1588  $guid = $this->getGUID();
1589  if ($guid > 0) {
1590  return $this->update();
1591  } else {
1592  $guid = $this->create();
1593  if ($guid) {
1594  if (_elgg_services()->events->trigger('create', $this->type, $this)) {
1595  return $guid;
1596  } else {
1597  // plugins that return false to event don't need to override the access system
1598  $ia = elgg_set_ignore_access(true);
1599  $this->delete();
1601  }
1602  }
1603  }
1604 
1605  return false;
1606  }
1607 
1621  protected function create() {
1622  global $CONFIG;
1623 
1624  // Using attribute array directly; get function does something special!
1625  $type = $this->getDatabase()->sanitizeString($this->attributes['type']);
1626  if ($type == "") {
1627  throw new \InvalidParameterException("Entity type must be set.");
1628  }
1629 
1630  $subtype = $this->attributes['subtype'];
1631  $subtype_id = add_subtype($type, $subtype);
1632  $owner_guid = (int)$this->attributes['owner_guid'];
1633  $access_id = (int)$this->attributes['access_id'];
1634  $now = (string)time();
1635  $time_created = isset($this->attributes['time_created']) ? (int)$this->attributes['time_created'] : $now;
1636 
1637  $site_guid = $this->attributes['site_guid'];
1638  if ($site_guid == 0) {
1639  $site_guid = $CONFIG->site_guid;
1640  }
1641  $site_guid = (int)$site_guid;
1642 
1643  $container_guid = $this->attributes['container_guid'];
1644  if ($container_guid == 0) {
1646  $this->attributes['container_guid'] = $container_guid;
1647  }
1649 
1650  if ($access_id == ACCESS_DEFAULT) {
1651  throw new \InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.h');
1652  }
1653 
1654  $owner = $this->getOwnerEntity();
1655  if ($owner && !$owner->canWriteToContainer(0, $type, $subtype)) {
1656  return false;
1657  }
1658 
1659  if ($owner_guid != $container_guid) {
1660  $container = $this->getContainerEntity();
1661  if ($container && !$container->canWriteToContainer(0, $type, $subtype)) {
1662  return false;
1663  }
1664  }
1665 
1666  $result = $this->getDatabase()->insertData("INSERT into {$CONFIG->dbprefix}entities
1667  (type, subtype, owner_guid, site_guid, container_guid,
1668  access_id, time_created, time_updated, last_action)
1669  values
1670  ('$type', $subtype_id, $owner_guid, $site_guid, $container_guid,
1671  $access_id, $time_created, $now, $now)");
1672 
1673  if (!$result) {
1674  throw new \IOException("Unable to save new object's base entity information!");
1675  }
1676 
1677  // for BC with 1.8, ->subtype always returns ID, ->getSubtype() the string
1678  $this->attributes['subtype'] = (int)$subtype_id;
1679  $this->attributes['guid'] = (int)$result;
1680  $this->attributes['time_created'] = (int)$time_created;
1681  $this->attributes['time_updated'] = (int)$now;
1682  $this->attributes['last_action'] = (int)$now;
1683  $this->attributes['site_guid'] = (int)$site_guid;
1684  $this->attributes['container_guid'] = (int)$container_guid;
1685 
1686  // Save any unsaved metadata
1687  if (sizeof($this->temp_metadata) > 0) {
1688  foreach ($this->temp_metadata as $name => $value) {
1689  $this->$name = $value;
1690  }
1691 
1692  $this->temp_metadata = array();
1693  }
1694 
1695  // Save any unsaved annotations.
1696  if (sizeof($this->temp_annotations) > 0) {
1697  foreach ($this->temp_annotations as $name => $value) {
1698  $this->annotate($name, $value);
1699  }
1700 
1701  $this->temp_annotations = array();
1702  }
1703 
1704  // Save any unsaved private settings.
1705  if (sizeof($this->temp_private_settings) > 0) {
1706  foreach ($this->temp_private_settings as $name => $value) {
1707  $this->setPrivateSetting($name, $value);
1708  }
1709 
1710  $this->temp_private_settings = array();
1711  }
1712 
1713  _elgg_cache_entity($this);
1714 
1715  return $result;
1716  }
1717 
1725  protected function update() {
1726  global $CONFIG;
1727 
1728  // See #5600. This ensures canEdit() checks the BD persisted entity so it sees the
1729  // persisted owner_guid, container_guid, etc.
1730  _elgg_disable_caching_for_entity($this->guid);
1731  $persisted_entity = get_entity($this->guid);
1732  if (!$persisted_entity) {
1733  // Why worry about this case? If access control was off when the user fetched this object but
1734  // was turned back on again. Better to just bail than to turn access control off again.
1735  return false;
1736  }
1737 
1738  $allow_edit = $persisted_entity->canEdit();
1739  unset($persisted_entity);
1740 
1741  if ($allow_edit) {
1742  // give old update event a chance to stop the update
1743  $allow_edit = _elgg_services()->events->trigger('update', $this->type, $this);
1744  }
1745 
1746  _elgg_enable_caching_for_entity($this->guid);
1747 
1748  if (!$allow_edit) {
1749  return false;
1750  }
1751 
1752  // See #6225. We copy these after the update event in case a handler changed one of them.
1753  $guid = (int)$this->guid;
1754  $owner_guid = (int)$this->owner_guid;
1755  $access_id = (int)$this->access_id;
1756  $container_guid = (int)$this->container_guid;
1757  $time_created = (int)$this->time_created;
1758  $time = time();
1759 
1760  if ($access_id == ACCESS_DEFAULT) {
1761  throw new \InvalidParameterException('ACCESS_DEFAULT is not a valid access level. See its documentation in elgglib.php');
1762  }
1763 
1764  $ret = $this->getDatabase()->updateData("UPDATE {$CONFIG->dbprefix}entities
1765  set owner_guid='$owner_guid', access_id='$access_id',
1766  container_guid='$container_guid', time_created='$time_created',
1767  time_updated='$time' WHERE guid=$guid");
1768 
1769  elgg_trigger_after_event('update', $this->type, $this);
1770 
1771  // TODO(evan): Move this to \ElggObject?
1772  if ($this instanceof \ElggObject) {
1773  update_river_access_by_object($guid, $access_id);
1774  }
1775 
1776  // If memcache is available then delete this entry from the cache
1777  static $newentity_cache;
1778  if ((!$newentity_cache) && (is_memcache_available())) {
1779  $newentity_cache = new \ElggMemcache('new_entity_cache');
1780  }
1781  if ($newentity_cache) {
1782  $newentity_cache->delete($guid);
1783  }
1784 
1785  if ($ret !== false) {
1786  $this->attributes['time_updated'] = $time;
1787  }
1788 
1789  _elgg_cache_entity($this);
1790 
1791  // Handle cases where there was no error BUT no rows were updated!
1792  return $ret !== false;
1793  }
1794 
1802  protected function load($guid) {
1803  if ($guid instanceof \stdClass) {
1804  $row = $guid;
1805  } else {
1807  }
1808 
1809  if ($row) {
1810  // Create the array if necessary - all subclasses should test before creating
1811  if (!is_array($this->attributes)) {
1812  $this->attributes = array();
1813  }
1814 
1815  // Now put these into the attributes array as core values
1816  $objarray = (array) $row;
1817  foreach ($objarray as $key => $value) {
1818  $this->attributes[$key] = $value;
1819  }
1820 
1821  // Increment the portion counter
1822  if (!$this->isFullyLoaded()) {
1823  $this->tables_loaded++;
1824  }
1825 
1826  // guid needs to be an int https://github.com/elgg/elgg/issues/4111
1827  $this->attributes['guid'] = (int)$this->attributes['guid'];
1828 
1829  // for BC with 1.8, ->subtype always returns ID, ->getSubtype() the string
1830  $this->attributes['subtype'] = (int)$this->attributes['subtype'];
1831 
1832  // Cache object handle
1833  if ($this->attributes['guid']) {
1834  _elgg_cache_entity($this);
1835  }
1836 
1837  return true;
1838  }
1839 
1840  return false;
1841  }
1842 
1849  protected function loadAdditionalSelectValues(array $data) {
1850  foreach ($data as $name => $value) {
1851  $this->setVolatileData("select:$name", $value);
1852  }
1853  }
1854 
1867  public function refresh(\stdClass $row) {
1868  if ($row instanceof \stdClass) {
1869  return $this->load($row);
1870  }
1871  return false;
1872  }
1873 
1893  public function disable($reason = "", $recursive = true) {
1894  if (!$this->guid) {
1895  return false;
1896  }
1897 
1898  if (!_elgg_services()->events->trigger('disable', $this->type, $this)) {
1899  return false;
1900  }
1901 
1902  if (!$this->canEdit()) {
1903  return false;
1904  }
1905 
1906  if ($this instanceof ElggUser && $this->banned === 'no') {
1907  // temporarily ban to prevent using the site during disable
1908  _elgg_services()->usersTable->markBanned($this->guid, true);
1909  $unban_after = true;
1910  } else {
1911  $unban_after = false;
1912  }
1913 
1914  _elgg_invalidate_cache_for_entity($this->guid);
1915 
1916  if ($reason) {
1917  $this->disable_reason = $reason;
1918  }
1919 
1920  global $CONFIG;
1921  $guid = (int)$this->guid;
1922 
1923  if ($recursive) {
1926  $ia = elgg_set_ignore_access(true);
1927 
1928  $query = "
1929  SELECT *
1930  FROM {$CONFIG->dbprefix}entities
1931  WHERE (
1932  container_guid = $guid
1933  OR owner_guid = $guid
1934  OR site_guid = $guid
1935  )
1936  AND enabled = 'yes'
1937  ";
1938  $sub_entities = $this->getDatabase()->getData($query, 'entity_row_to_elggstar');
1939 
1940  if ($sub_entities) {
1941  /* @var ElggEntity[] $sub_entities */
1942  foreach ($sub_entities as $e) {
1943  add_entity_relationship($e->guid, 'disabled_with', $this->guid);
1944  $e->disable($reason);
1945  }
1946  }
1947 
1950  }
1951 
1952  $this->disableMetadata();
1953  $this->disableAnnotations();
1954 
1955  $res = $this->getDatabase()->updateData("
1956  UPDATE {$CONFIG->dbprefix}entities
1957  SET enabled = 'no'
1958  WHERE guid = $guid
1959  ");
1960 
1961  if ($unban_after) {
1962  _elgg_services()->usersTable->markBanned($this->guid, false);
1963  }
1964 
1965  if ($res) {
1966  $this->attributes['enabled'] = 'no';
1967  _elgg_services()->events->trigger('disable:after', $this->type, $this);
1968  }
1969 
1970  return $res;
1971  }
1972 
1983  public function enable($recursive = true) {
1984  $guid = (int)$this->guid;
1985  if (!$guid) {
1986  return false;
1987  }
1988 
1989  if (!_elgg_services()->events->trigger('enable', $this->type, $this)) {
1990  return false;
1991  }
1992 
1993  if (!$this->canEdit()) {
1994  return false;
1995  }
1996 
1997  global $CONFIG;
1998 
1999  // Override access only visible entities
2000  $old_access_status = access_get_show_hidden_status();
2002 
2003  $result = $this->getDatabase()->updateData("UPDATE {$CONFIG->dbprefix}entities
2004  SET enabled = 'yes'
2005  WHERE guid = $guid");
2006 
2007  $this->deleteMetadata('disable_reason');
2008  $this->enableMetadata();
2009  $this->enableAnnotations();
2010 
2011  if ($recursive) {
2012  $disabled_with_it = elgg_get_entities_from_relationship(array(
2013  'relationship' => 'disabled_with',
2014  'relationship_guid' => $guid,
2015  'inverse_relationship' => true,
2016  'limit' => 0,
2017  ));
2018 
2019  foreach ($disabled_with_it as $e) {
2020  $e->enable();
2021  remove_entity_relationship($e->guid, 'disabled_with', $guid);
2022  }
2023  }
2024 
2025  access_show_hidden_entities($old_access_status);
2026 
2027  if ($result) {
2028  $this->attributes['enabled'] = 'yes';
2029  _elgg_services()->events->trigger('enable:after', $this->type, $this);
2030  }
2031 
2032  return $result;
2033  }
2034 
2040  public function isEnabled() {
2041  return $this->enabled == 'yes';
2042  }
2043 
2061  public function delete($recursive = true) {
2062  global $CONFIG;
2063 
2064  $guid = $this->guid;
2065  if (!$guid) {
2066  return false;
2067  }
2068 
2069  // first check if we can delete this entity
2070  // NOTE: in Elgg <= 1.10.3 this was after the delete event,
2071  // which could potentially remove some content if the user didn't have access
2072  if (!$this->canDelete()) {
2073  return false;
2074  }
2075 
2076  // now trigger an event to let others know this entity is about to be deleted
2077  // so they can prevent it or take their own actions
2078  if (!_elgg_services()->events->trigger('delete', $this->type, $this)) {
2079  return false;
2080  }
2081 
2082  if ($this instanceof ElggUser) {
2083  // ban to prevent using the site during delete
2084  _elgg_services()->usersTable->markBanned($this->guid, true);
2085  }
2086 
2088 
2089  // If memcache is available then delete this entry from the cache
2090  static $newentity_cache;
2091  if ((!$newentity_cache) && (is_memcache_available())) {
2092  $newentity_cache = new \ElggMemcache('new_entity_cache');
2093  }
2094  if ($newentity_cache) {
2095  $newentity_cache->delete($guid);
2096  }
2097 
2098  // Delete contained owned and otherwise releated objects (depth first)
2099  if ($recursive) {
2100  // Temporarily overriding access controls
2101  $entity_disable_override = access_get_show_hidden_status();
2103  $ia = elgg_set_ignore_access(true);
2104 
2105  // @todo there was logic in the original code that ignored
2106  // entities with owner or container guids of themselves.
2107  // this should probably be prevented in \ElggEntity instead of checked for here
2108  $options = array(
2109  'wheres' => array(
2110  "((container_guid = $guid OR owner_guid = $guid OR site_guid = $guid)"
2111  . " AND guid != $guid)"
2112  ),
2113  'limit' => 0
2114  );
2115 
2116  $batch = new \ElggBatch('elgg_get_entities', $options);
2117  $batch->setIncrementOffset(false);
2118 
2119  foreach ($batch as $e) {
2120  $e->delete(true);
2121  }
2122 
2123  access_show_hidden_entities($entity_disable_override);
2125  }
2126 
2127  $entity_disable_override = access_get_show_hidden_status();
2129  $ia = elgg_set_ignore_access(true);
2130 
2131  // Now delete the entity itself
2132  $this->deleteMetadata();
2133  $this->deleteOwnedMetadata();
2134  $this->deleteAnnotations();
2135  $this->deleteOwnedAnnotations();
2136  $this->deleteRelationships();
2139 
2140  access_show_hidden_entities($entity_disable_override);
2142 
2143  elgg_delete_river(array('subject_guid' => $guid));
2144  elgg_delete_river(array('object_guid' => $guid));
2145  elgg_delete_river(array('target_guid' => $guid));
2147 
2148  $res = $this->getDatabase()->deleteData("
2149  DELETE FROM {$CONFIG->dbprefix}entities
2150  WHERE guid = $guid
2151  ");
2152 
2153  if ($res && in_array($this->type, ['object', 'user', 'group', 'site'])) {
2154  // delete from secondary table
2155  $sub_table = "{$CONFIG->dbprefix}{$this->type}s_entity";
2156 
2157  $this->getDatabase()->deleteData("
2158  DELETE FROM $sub_table
2159  WHERE guid = $guid
2160  ");
2161  }
2162 
2163  _elgg_clear_entity_files($this);
2164 
2165  return (bool)$res;
2166  }
2167 
2171  public function toObject() {
2172  $object = $this->prepareObject(new \stdClass());
2173  $params = array('entity' => $this);
2174  $object = _elgg_services()->hooks->trigger('to:object', 'entity', $params, $object);
2175  return $object;
2176  }
2177 
2184  protected function prepareObject($object) {
2185  $object->guid = $this->guid;
2186  $object->type = $this->getType();
2187  $object->subtype = $this->getSubtype();
2188  $object->owner_guid = $this->getOwnerGUID();
2189  $object->container_guid = $this->getContainerGUID();
2190  $object->site_guid = (int)$this->site_guid;
2191  $object->time_created = date('c', $this->getTimeCreated());
2192  $object->time_updated = date('c', $this->getTimeUpdated());
2193  $object->url = $this->getURL();
2194  $object->read_access = (int)$this->access_id;
2195  return $object;
2196  }
2197 
2198  /*
2199  * LOCATABLE INTERFACE
2200  */
2201 
2207  public function getLocation() {
2208  return $this->location;
2209  }
2210 
2218  public function setLocation($location) {
2219  $this->location = $location;
2220  }
2221 
2231  public function setLatLong($lat, $long) {
2232  $this->{"geo:lat"} = $lat;
2233  $this->{"geo:long"} = $long;
2234  }
2235 
2242  public function getLatitude() {
2243  return (float)$this->{"geo:lat"};
2244  }
2245 
2252  public function getLongitude() {
2253  return (float)$this->{"geo:long"};
2254  }
2255 
2256  /*
2257  * NOTABLE INTERFACE
2258  */
2259 
2274  public function setCalendarTimeAndDuration($hour = null, $minute = null, $second = null,
2275  $day = null, $month = null, $year = null, $duration = null) {
2276  elgg_deprecated_notice(__METHOD__ . ' has been deprecated', 1.9);
2277 
2278  $start = mktime($hour, $minute, $second, $month, $day, $year);
2279  $end = $start + abs($duration);
2280  if (!$duration) {
2281  $end = get_day_end($day, $month, $year);
2282  }
2283 
2284  $this->calendar_start = $start;
2285  $this->calendar_end = $end;
2286 
2287  return true;
2288  }
2289 
2296  public function getCalendarStartTime() {
2297  elgg_deprecated_notice(__METHOD__ . ' has been deprecated', 1.9);
2298  return (int)$this->calendar_start;
2299  }
2300 
2307  public function getCalendarEndTime() {
2308  elgg_deprecated_notice(__METHOD__ . ' has been deprecated', 1.9);
2309  return (int)$this->calendar_end;
2310  }
2311 
2312  /*
2313  * EXPORTABLE INTERFACE
2314  */
2315 
2322  public function getExportableValues() {
2323  elgg_deprecated_notice(__METHOD__ . ' has been deprecated by toObject()', 1.9);
2324  return array(
2325  'guid',
2326  'type',
2327  'subtype',
2328  'time_created',
2329  'time_updated',
2330  'container_guid',
2331  'owner_guid',
2332  'site_guid'
2333  );
2334  }
2335 
2344  public function export() {
2345  elgg_deprecated_notice(__METHOD__ . ' has been deprecated', 1.9);
2346  $tmp = array();
2347 
2348  // Generate uuid
2349  $uuid = guid_to_uuid($this->getGUID());
2350 
2351  // Create entity
2352  $odd = new ODDEntity(
2353  $uuid,
2354  $this->attributes['type'],
2355  get_subtype_from_id($this->attributes['subtype'])
2356  );
2357 
2358  $tmp[] = $odd;
2359 
2361 
2362  // Now add its attributes
2363  foreach ($this->attributes as $k => $v) {
2364  $meta = null;
2365 
2366  if (in_array($k, $exportable_values)) {
2367  switch ($k) {
2368  case 'guid': // Dont use guid in OpenDD
2369  case 'type': // Type and subtype already taken care of
2370  case 'subtype':
2371  break;
2372 
2373  case 'time_created': // Created = published
2374  $odd->setAttribute('published', date("r", $v));
2375  break;
2376 
2377  case 'site_guid': // Container
2378  $k = 'site_uuid';
2379  $v = guid_to_uuid($v);
2380  $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
2381  break;
2382 
2383  case 'container_guid': // Container
2384  $k = 'container_uuid';
2385  $v = guid_to_uuid($v);
2386  $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
2387  break;
2388 
2389  case 'owner_guid': // Convert owner guid to uuid, this will be stored in metadata
2390  $k = 'owner_uuid';
2391  $v = guid_to_uuid($v);
2392  $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
2393  break;
2394 
2395  default:
2396  $meta = new ODDMetaData($uuid . "attr/$k/", $uuid, $k, $v);
2397  }
2398 
2399  // set the time of any metadata created
2400  if ($meta) {
2401  $meta->setAttribute('published', date("r", $this->time_created));
2402  $tmp[] = $meta;
2403  }
2404  }
2405  }
2406 
2407  // Now we do something a bit special.
2408  /*
2409  * This provides a rendered view of the entity to foreign sites.
2410  */
2411 
2412  elgg_set_viewtype('default');
2413  $view = elgg_view_entity($this, array('full_view' => true));
2415 
2416  $tmp[] = new ODDMetaData($uuid . "volatile/renderedentity/", $uuid,
2417  'renderedentity', $view, 'volatile');
2418 
2419  return $tmp;
2420  }
2421 
2422  /*
2423  * IMPORTABLE INTERFACE
2424  */
2425 
2436  public function import(ODD $data) {
2437  elgg_deprecated_notice(__METHOD__ . ' has been deprecated', 1.9);
2438  if (!($data instanceof ODDEntity)) {
2439  throw new \InvalidParameterException("import() passed an unexpected ODD class");
2440  }
2441 
2442  // Set type and subtype
2443  $this->attributes['type'] = $data->getAttribute('class');
2444  $this->attributes['subtype'] = $data->getAttribute('subclass');
2445 
2446  // Set owner
2447  $this->attributes['owner_guid'] = _elgg_services()->session->getLoggedInUserGuid(); // Import as belonging to importer.
2448 
2449  // Set time
2450  $this->attributes['time_created'] = strtotime($data->getAttribute('published'));
2451  $this->attributes['time_updated'] = time();
2452 
2453  return true;
2454  }
2455 
2456  /*
2457  * SYSTEM LOG INTERFACE
2458  */
2459 
2466  public function getSystemLogID() {
2467  return $this->getGUID();
2468  }
2469 
2477  public function getObjectFromID($id) {
2478  return get_entity($id);
2479  }
2480 
2490  public function getTags($tag_names = null) {
2491  if ($tag_names && !is_array($tag_names)) {
2492  $tag_names = array($tag_names);
2493  }
2494 
2496  $entity_tags = array();
2497 
2498  foreach ($valid_tags as $tag_name) {
2499  if (is_array($tag_names) && !in_array($tag_name, $tag_names)) {
2500  continue;
2501  }
2502 
2503  if ($tags = $this->$tag_name) {
2504  // if a single tag, metadata returns a string.
2505  // if multiple tags, metadata returns an array.
2506  if (is_array($tags)) {
2507  $entity_tags = array_merge($entity_tags, $tags);
2508  } else {
2509  $entity_tags[] = $tags;
2510  }
2511  }
2512  }
2513 
2514  return $entity_tags;
2515  }
2516 
2524 
2525  if (!$this->guid) {
2526  return false;
2527  }
2528 
2529  if ($this->type !== 'user') {
2530  return true;
2531  }
2532 
2533  $ac = _elgg_services()->accessCollections;
2534 
2535  $collections = $ac->getCollectionsByMember($this->guid);
2536  if (empty($collections)) {
2537  return true;
2538  }
2539 
2540  $result = true;
2541  foreach ($collections as $collection) {
2542  $result = $result & $ac->removeUser($this->guid, $collection->id);
2543  }
2544 
2545  return $result;
2546  }
2547 
2554  public function deleteOwnedAccessCollections() {
2555 
2556  if (!$this->guid) {
2557  return false;
2558  }
2559 
2560  $ac = _elgg_services()->accessCollections;
2561 
2562  $collections = $ac->getEntityCollections($this->guid);
2563  if (empty($collections)) {
2564  return true;
2565  }
2566 
2567  $result = true;
2568  foreach ($collections as $collection) {
2569  $result = $result & $ac->delete($collection->id);
2570  }
2571 
2572  return $result;
2573  }
2574 }
_elgg_disable_caching_for_entity($guid)
Remove this entity from the entity cache and make sure it is not re-added.
Definition: entities.php:35
$tags
Definition: summary.php:41
deleteOwnedAccessCollections()
Remove all access collections owned by this entity.
enable($recursive=true)
Enable the entity.
$view
Definition: crop.php:68
canComment($user_guid=0)
Can a user comment on an entity?
getSubtype()
Get the entity subtype.
$r
canEditMetadata($metadata=null, $user_guid=0)
Can a user edit metadata on this entity?
getIcon($size= 'medium')
Returns a URL for the entity&#39;s icon.
getDatabase()
Provides a pointer to the database object.
Definition: ElggData.php:67
elgg_get_registered_tag_metadata_names()
Returns an array of valid metadata names for tags.
Definition: tags.php:236
refresh(\stdClass $row)
Load new data from database into existing entity.
elgg_disable_metadata(array $options)
Disables metadata based on $options.
Definition: metadata.php:171
getOwnerGUID()
Get the guid of the entity&#39;s owner.
getTimeCreated()
Returns the UNIX epoch time that this entity was created.
Definition: ElggData.php:131
__clone()
Clone an entity.
Definition: ElggEntity.php:150
_elgg_invalidate_cache_for_entity($guid)
Invalidate this class&#39;s entry in the cache.
Definition: entities.php:63
getAnnotations($options=array(), $limit=50, $offset=0, $order="asc")
Gets an array of annotations.
Definition: ElggEntity.php:855
__get($name)
Get an attribute or metadata value.
Definition: ElggEntity.php:256
create_annotation($entity_guid, $name, $value, $value_type= '', $owner_guid=0, $access_id=ACCESS_PRIVATE)
Create a new annotation.
Definition: annotations.php:62
loadAdditionalSelectValues(array $data)
Stores non-attributes from the loading of the entity as volatile data.
getOwnerEntity()
Gets the that owns this entity.
remove_all_private_settings($entity_guid)
Deletes all private settings for an entity.
add_entity_relationship($guid_one, $relationship, $guid_two)
Create a relationship between two entities.
elgg_normalize_url($url)
Definition: output.php:311
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
setLatLong($lat, $long)
Set latitude and longitude metadata tags for a given entity.
removePrivateSetting($name)
Removes private setting.
Definition: ElggEntity.php:706
disableAnnotations($name= '')
Disables annotations for this entity, optionally based on name.
Definition: ElggEntity.php:764
prepareObject($object)
Prepare an object copy for toObject()
remove_entity_relationship($guid_one, $relationship, $guid_two)
Delete a relationship between two entities.
$size
Definition: view.php:10
deleteMetadata($name=null)
Deletes all metadata on this object (metadata.entity_guid = $this->guid).
Definition: ElggEntity.php:468
elgg_delete_annotations(array $options)
Deletes annotations based on $options.
countAnnotations($name="")
Count annotations.
Definition: ElggEntity.php:914
$e
Definition: metadata.php:12
setCalendarTimeAndDuration($hour=null, $minute=null, $second=null, $day=null, $month=null, $year=null, $duration=null)
Set the time and duration of an object.
deleteAnnotations($name=null)
Deletes all annotations on this object (annotations.entity_guid = $this->guid).
Definition: ElggEntity.php:720
$object
Definition: upgrade.php:12
$CONFIG site_guid
The guid of the current site object.
Definition: config.php:122
setPrivateSetting($name, $value)
Adds a private setting to this entity.
Definition: ElggEntity.php:672
initializeAttributes()
Initialize the attributes array.
Definition: ElggEntity.php:102
canWriteToContainer($user_guid=0, $type= 'all', $subtype= 'all')
Can a user add an entity to this container.
$exportable_values
Definition: entity.php:23
getPrivateSetting($name)
Returns a private setting value.
Definition: ElggEntity.php:688
deleteOwnedMetadata($name=null)
Deletes all metadata owned by this object (metadata.owner_guid = $this->guid).
Definition: ElggEntity.php:493
$metadata
Definition: entity.php:19
getAnnotationsMax($name)
Get the maximum of integer type annotations of a given name.
Definition: ElggEntity.php:958
countComments()
Count the number of comments attached to this entity.
Definition: ElggEntity.php:968
get_subtype_from_id($subtype_id)
Gets the denormalized string for a given subtype ID.
Definition: entities.php:169
save()
Save an entity.
setMetadata($name, $value, $value_type= '', $multiple=false, $owner_guid=0, $access_id=null)
Set metadata on this entity.
Definition: ElggEntity.php:389
deleteOwnedAnnotations($name=null)
Deletes all annotations owned by this object (annotations.owner_guid = $this->guid).
Definition: ElggEntity.php:740
$data
Definition: opendd.php:13
_elgg_cache_entity(\ElggEntity $entity)
Cache an entity.
Definition: entities.php:92
$value
Definition: longtext.php:26
$ia
Definition: upgrade.php:26
isFullyLoaded()
Tests to see whether the object has been fully loaded.
$return
Definition: opendd.php:15
if(!$count) $offset
Definition: pagination.php:26
getGUID()
Returns the guid.
disableMetadata($name= '')
Disables metadata for this entity, optionally based on name.
Definition: ElggEntity.php:531
$guid
Removes an admin notice.
getContainerGUID()
Gets the container GUID for this entity.
getCalendarStartTime()
Returns the start timestamp.
$collection
getTimeUpdated()
Returns the UNIX epoch time that this entity was last updated.
_elgg_enable_caching_for_entity($guid)
Allow this entity to be stored in the entity cache.
Definition: entities.php:49
enableAnnotations($name= '')
Enables annotations for this entity, optionally based on name.
Definition: ElggEntity.php:785
elgg_strtolower()
Wrapper function for mb_strtolower().
Definition: mb_wrapper.php:174
canEdit($user_guid=0)
Can a user edit this entity?
export()
Export this class into an array of ODD Elements containing all necessary fields.
events($event="", $object_type="", $function="", $priority=500, $call=false, $object=null)
Deprecated events core function.
$url
Definition: exceptions.php:24
$icon_override
Icon override, overrides the value of getIcon().
Definition: ElggEntity.php:55
remove_entity_relationships($guid, $relationship="", $inverse_relationship=false, $type= '')
Removes all relationships originating from a particular entity.
getAnnotationsSum($name)
Get the sum of integer type annotations of a given name.
Definition: ElggEntity.php:936
getSites($options=array())
Gets the sites this entity is a member of.
clearRelationships()
Remove all relationships to and from this entity.
Definition: ElggEntity.php:626
setVolatileData($name, $value)
Set a piece of volatile (non-persisted) data on this entity.
Definition: ElggEntity.php:591
get_day_end($day=null, $month=null, $year=null)
Return a timestamp for the end of a given day (defaults today).
getContainer()
Gets the container GUID for this entity.
$params
Definition: login.php:72
$options
Definition: index.php:14
setContainerGUID($container_guid)
Set the container for this object.
removeRelationship($guid_two, $relationship)
Remove a relationship.
Definition: ElggEntity.php:657
elgg_disable_annotations(array $options)
Disables annotations based on $options.
update_river_access_by_object($object_guid, $access_id)
Sets the access ID on river items for a particular object.
Definition: river.php:714
countEntitiesFromRelationship($relationship, $inverse_relationship=false)
Gets the number of entities from a specific relationship type.
getMetadata($name)
Return the value of a piece of metadata.
Definition: ElggEntity.php:302
setContainer($container_guid)
Set the container for this object.
getEntitiesFromRelationship($options=array(), $inverse=false, $limit=50, $offset=0)
Gets an array of entities with a relationship to this entity.
Definition: ElggEntity.php:998
$owner_guid
deleteRelationships($relationship=null)
Remove all relationships to and from this entity.
Definition: ElggEntity.php:612
metadata_array_to_values($array)
Takes a metadata array (which has all kinds of properties) and turns it into a simple array of string...
Definition: metadata.php:311
getExportableValues()
Returns an array of fields which can be exported.
elgg_instanceof($entity, $type=null, $subtype=null, $class=null)
Checks if $entity is an and optionally for type and subtype.
Definition: entities.php:926
getTags($tag_names=null)
Returns tags for this entity.
if($entity) $container
Definition: access.php:62
$limit
Definition: userpicker.php:38
add_subtype($type, $subtype, $class="")
Register with a certain type and subtype to be loaded as a specific class.
Definition: entities.php:248
elgg_set_viewtype($viewtype="")
Manually set the viewtype.
Definition: views.php:70
annotate($name, $value, $access_id=ACCESS_PRIVATE, $owner_guid=0, $vartype="")
Adds an annotation to an entity.
Definition: ElggEntity.php:831
$temp_annotations
Holds annotations until entity is saved.
Definition: ElggEntity.php:67
getVolatileData($name)
Get a piece of volatile (non-persisted) data on this entity.
Definition: ElggEntity.php:571
$filehandler owner_guid
Definition: crop.php:21
remove_private_setting($entity_guid, $name)
Deletes a private setting for an entity.
elgg_enable_metadata(array $options)
Enables metadata based on $options.
Definition: metadata.php:187
$owner
Definition: crop.php:8
$key
Definition: summary.php:34
get_user($guid)
Get a user object from a GUID.
Definition: users.php:87
elgg_set_ignore_access($ignore=true)
Set if Elgg&#39;s access system should be ignored.
Definition: access.php:43
getAnnotationsAvg($name)
Get the average of an integer type annotation.
Definition: ElggEntity.php:925
_elgg_services()
Definition: autoloader.php:14
global $CONFIG
create_metadata($entity_guid, $name, $value, $value_type= '', $owner_guid=0, $access_id=ACCESS_PRIVATE, $allow_multiple=false)
Create a new metadata object, or update an existing one.
Definition: metadata.php:65
can_write_to_container($user_guid=0, $container_guid=0, $type= 'all', $subtype= 'all')
Determine if a given user can write to an entity container.
Definition: entities.php:299
setLocation($location)
Sets the &#39;location&#39; metadata for the entity.
setIcon($url, $size= 'medium')
Set an icon override for an icon and size.
sanitise_string($string)
Wrapper function for alternate English spelling (.
Definition: database.php:150
$user
Definition: ban.php:13
$time_created
Definition: online.php:16
const ACCESS_PRIVATE
Definition: elgglib.php:1993
__set($name, $value)
Set an attribute or metadata value for this entity.
Definition: ElggEntity.php:197
const ELGG_ENTITIES_ANY_VALUE
Definition: elgglib.php:2006
$temp_metadata
Holds metadata until entity is saved.
Definition: ElggEntity.php:61
elgg_get_entities(array $options=array())
Returns an array of entities with optional filtering.
Definition: entities.php:494
canAnnotate($user_guid=0, $annotation_name= '')
Can a user annotate an entity?
elgg_enable_annotations(array $options)
Enables annotations based on $options.
clearMetadata($name= '')
Remove metadata.
Definition: ElggEntity.php:519
elgg_deprecated_notice($msg, $dep_version, $backtrace_level=1)
Log a notice about deprecated use of a function, view, etc.
Definition: elgglib.php:1031
elgg global
Pointer to the global context.
Definition: elgglib.js:12
getCalendarEndTime()
Returns the end timestamp.
getIconURL($params=array())
Get the URL for this entity&#39;s icon.
$type
Definition: add.php:8
access_get_show_hidden_status()
Return current status of showing disabled entities.
Definition: access.php:172
deleteAccessCollectionMemberships()
Remove the membership of all access collections for this entity (if the entity is a user) ...
isEnabled()
Is this entity enabled?
get_entity_as_row($guid)
Returns a database row from the entities table.
Definition: entities.php:352
elgg_extract($key, $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:1271
addRelationship($guid_two, $relationship)
Add a relationship between this an another entity.
Definition: ElggEntity.php:643
update()
Update the entity in the database.
getAccessID()
Returns the access_id.
guid_to_uuid($guid)
Generate a UUID from a given GUID.
$comment access_id
Definition: save.php:61
$temp_private_settings
Holds private settings until entity is saved.
Definition: ElggEntity.php:73
getOwner()
Return the guid of the entity&#39;s owner.
elgg_delete_metadata(array $options)
Deletes metadata based on $options.
Definition: metadata.php:158
canDelete($user_guid=0)
Can a user delete this entity?
access_show_hidden_entities($show_hidden)
Show or hide disabled entities.
Definition: access.php:159
$hidden
Definition: save.php:13
elgg_get_metadata(array $options=array())
Returns metadata.
Definition: metadata.php:143
getType()
Returns the entity type.
elgg_get_annotations(array $options=array())
Returns annotations.
Definition: ODD.php:9
setDisplayName($displayName)
Sets the title or name of this entity.
elgg_delete_river(array $options=array())
Delete river items.
Definition: river.php:162
clearAnnotations($name="")
Remove an annotation or all annotations for this entity.
Definition: ElggEntity.php:902
elgg_view_entity(\ElggEntity $entity, $vars=array(), $bypass=false, $debug=false)
Returns a string of a rendered entity.
Definition: views.php:779
create()
Create a new entry in the entities table.
elgg_trigger_after_event($event, $object_type, $object=null)
Trigger an "After event" indicating a process has finished.
Definition: elgglib.php:624
setURL($url)
Overrides the URL returned by getURL()
$row
set_private_setting($entity_guid, $name, $value)
Sets a private setting for an entity.
getLocation()
Gets the &#39;location&#39; metadata for the entity.
getLatitude()
Return the entity&#39;s latitude.
is_memcache_available()
Return true if memcache is available and configured.
Definition: memcache.php:16
$container_guid
getContainerEntity()
Get the container entity for this object.
elgg_get_entities_from_relationship($options)
Return entities matching a given query joining against a relationship.
removeFromSite($site)
Remove this entity from a site.
get_private_setting($entity_guid, $name)
Gets a private setting for an entity.
__unset($name)
Unset a property from metadata or attribute.
Definition: ElggEntity.php:361
$user_guid
Avatar remove action.
Definition: remove.php:6
const ACCESS_DEFAULT
Definition: elgglib.php:1992
$subtype
Definition: river.php:12
if(!$collection_name) $id
Definition: add.php:17
getSystemLogID()
Return an identification for the object for storage in the system log.
list style type
Definition: admin.php:753
enableMetadata($name= '')
Enables metadata for this entity, optionally based on name.
Definition: ElggEntity.php:552
disable($reason="", $recursive=true)
Disable this entity.
getURL()
Gets the URL for this entity.
load($guid)
Loads attributes from the entities table into the object.
_elgg_clear_entity_files($entity)
Removes all entity files.
Definition: filestore.php:415
getDisplayName()
Get the entity&#39;s display name.
getAnnotationsMin($name)
Get the minimum of integer type annotations of given name.
Definition: ElggEntity.php:947
getLongitude()
Return the entity&#39;s longitude.
get_entity($guid)
Loads and returns an entity object from a guid.
Definition: entities.php:382
getObjectFromID($id)
For a given ID, return the object associated with it.
addToSite($site)
Add this entity to a site.
$url_override
If set, overrides the value of getURL()
Definition: ElggEntity.php:50
$comment container_guid
Definition: save.php:60
$volatile
Volatile data structure for this object, allows for storage of data in-memory that isn&#39;t sync&#39;d back ...
Definition: ElggEntity.php:79