/** * Deletes the entity. * * Removes the entity and its metadata, annotations, relationships, * river entries, and private data. * * Optionally can remove entities contained and owned by this entity. * * @warning If deleting recursively, this bypasses ownership of items contained by * the entity. That means that if the container_guid = $this->guid, the item will * be deleted regardless of who owns it. * * @param bool $recursive If true (default) then all entities which are * owned or contained by $this will also be deleted. * * @return bool */ public function delete($recursive = true) { $guid = $this->guid; if (!$guid) { return false; } // first check if we can delete this entity // NOTE: in Elgg <= 1.10.3 this was after the delete event, // which could potentially remove some content if the user didn't have access if (!$this->canDelete()) { return false; } // now trigger an event to let others know this entity is about to be deleted // so they can prevent it or take their own actions if (!_elgg_services()->events->trigger('delete', $this->type, $this)) { return false; } if ($this instanceof ElggUser) { // ban to prevent using the site during delete _elgg_services()->usersTable->markBanned($this->guid, true); } // Delete contained owned and otherwise releated objects (depth first) if ($recursive) { // Temporarily overriding access controls $entity_disable_override = access_get_show_hidden_status(); access_show_hidden_entities(true); $ia = elgg_set_ignore_access(true); // @todo there was logic in the original code that ignored // entities with owner or container guids of themselves. // this should probably be prevented in \ElggEntity instead of checked for here $options = array('wheres' => array("((container_guid = {$guid} OR owner_guid = {$guid})" . " AND guid != {$guid})"), 'limit' => 0); $batch = new \ElggBatch('elgg_get_entities', $options); $batch->setIncrementOffset(false); foreach ($batch as $e) { $e->delete(true); } access_show_hidden_entities($entity_disable_override); elgg_set_ignore_access($ia); } $entity_disable_override = access_get_show_hidden_status(); access_show_hidden_entities(true); $ia = elgg_set_ignore_access(true); // Now delete the entity itself $this->deleteMetadata(); $this->deleteOwnedMetadata(); $this->deleteAnnotations(); $this->deleteOwnedAnnotations(); $this->deleteRelationships(); $this->deleteAccessCollectionMemberships(); $this->deleteOwnedAccessCollections(); access_show_hidden_entities($entity_disable_override); elgg_set_ignore_access($ia); _elgg_delete_river(array('subject_guid' => $guid)); _elgg_delete_river(array('object_guid' => $guid)); _elgg_delete_river(array('target_guid' => $guid)); remove_all_private_settings($guid); _elgg_invalidate_cache_for_entity($guid); _elgg_invalidate_memcache_for_entity($guid); $dbprefix = elgg_get_config('dbprefix'); $sql = "\n\t\t\tDELETE FROM {$dbprefix}entities\n\t\t\tWHERE guid = :guid\n\t\t"; $params = [':guid' => $guid]; $deleted = $this->getDatabase()->deleteData($sql, $params); if ($deleted && in_array($this->type, ['object', 'user', 'group', 'site'])) { // delete from type-specific subtable $sql = "\n\t\t\t\tDELETE FROM {$dbprefix}{$this->type}s_entity\n\t\t\t\tWHERE guid = :guid\n\t\t\t"; $this->getDatabase()->deleteData($sql, $params); } _elgg_clear_entity_files($this); return (bool) $deleted; }
/** * Deletes the entity. * * Removes the entity and its metadata, annotations, relationships, * river entries, and private data. * * Optionally can remove entities contained and owned by this entity. * * @warning If deleting recursively, this bypasses ownership of items contained by * the entity. That means that if the container_guid = $this->guid, the item will * be deleted regardless of who owns it. * * @param bool $recursive If true (default) then all entities which are * owned or contained by $this will also be deleted. * * @return bool */ public function delete($recursive = true) { global $CONFIG; $guid = $this->guid; if (!$guid) { return false; } // first check if we can delete this entity // NOTE: in Elgg <= 1.10.3 this was after the delete event, // which could potentially remove some content if the user didn't have access if (!$this->canDelete()) { return false; } // now trigger an event to let others know this entity is about to be deleted // so they can prevent it or take their own actions if (!_elgg_services()->events->trigger('delete', $this->type, $this)) { return false; } _elgg_invalidate_cache_for_entity($guid); // If memcache is available then delete this entry from the cache static $newentity_cache; if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new \ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $newentity_cache->delete($guid); } // Delete contained owned and otherwise releated objects (depth first) if ($recursive) { // Temporarily overriding access controls $entity_disable_override = access_get_show_hidden_status(); access_show_hidden_entities(true); $ia = elgg_set_ignore_access(true); // @todo there was logic in the original code that ignored // entities with owner or container guids of themselves. // this should probably be prevented in \ElggEntity instead of checked for here $options = array('wheres' => array("((container_guid = {$guid} OR owner_guid = {$guid} OR site_guid = {$guid})" . " AND guid != {$guid})"), 'limit' => 0); $batch = new \ElggBatch('elgg_get_entities', $options); $batch->setIncrementOffset(false); foreach ($batch as $e) { $e->delete(true); } access_show_hidden_entities($entity_disable_override); elgg_set_ignore_access($ia); } $entity_disable_override = access_get_show_hidden_status(); access_show_hidden_entities(true); $ia = elgg_set_ignore_access(true); // Now delete the entity itself $this->deleteMetadata(); $this->deleteOwnedMetadata(); $this->deleteAnnotations(); $this->deleteOwnedAnnotations(); $this->deleteRelationships(); $this->deleteAccessCollectionMemberships(); $this->deleteOwnedAccessCollections(); access_show_hidden_entities($entity_disable_override); elgg_set_ignore_access($ia); elgg_delete_river(array('subject_guid' => $guid)); elgg_delete_river(array('object_guid' => $guid)); elgg_delete_river(array('target_guid' => $guid)); remove_all_private_settings($guid); $res = $this->getDatabase()->deleteData("DELETE FROM {$CONFIG->dbprefix}entities WHERE guid = {$guid}"); if ($res) { $sub_table = ""; // Where appropriate delete the sub table switch ($this->type) { case 'object': $sub_table = $CONFIG->dbprefix . 'objects_entity'; break; case 'user': $sub_table = $CONFIG->dbprefix . 'users_entity'; break; case 'group': $sub_table = $CONFIG->dbprefix . 'groups_entity'; break; case 'site': $sub_table = $CONFIG->dbprefix . 'sites_entity'; break; } if ($sub_table) { $this->getDatabase()->deleteData("DELETE FROM {$sub_table} WHERE guid = {$guid}"); } } _elgg_clear_entity_files($this); return (bool) $res; }