public function testSubtypeIsString() { $this->assertTrue($this->entity->save()); $guid = $this->entity->guid; _elgg_invalidate_cache_for_entity($guid); $this->entity = null; $this->entity = get_entity($guid); $this->assertEqual('elgg_entity_test_subtype', $this->entity->subtype); }
public function testGetSubtype() { $guid = $this->entity->guid; $this->assertEqual($this->entity->getSubtype(), 'elgg_entity_test_subtype'); _elgg_invalidate_cache_for_entity($guid); $this->entity = null; $this->entity = get_entity($guid); $this->assertEqual($this->entity->getSubtype(), 'elgg_entity_test_subtype'); }
// Bring all child elements forward $parent = $page->parent_guid; $children = elgg_get_entities_from_metadata(array('metadata_name' => 'parent_guid', 'metadata_value' => $page->getGUID())); if ($children) { $db_prefix = elgg_get_config('dbprefix'); $subtype_id = (int) get_subtype_id('object', 'page_top'); $newentity_cache = is_memcache_available() ? new ElggMemcache('new_entity_cache') : null; foreach ($children as $child) { if ($parent) { $child->parent_guid = $parent; } else { // If no parent, we need to transform $child to a page_top $child_guid = (int) $child->guid; update_data("UPDATE {$db_prefix}entities\n\t\t\t\t\t\tSET subtype = {$subtype_id} WHERE guid = {$child_guid}"); elgg_delete_metadata(array('guid' => $child_guid, 'metadata_name' => 'parent_guid')); _elgg_invalidate_cache_for_entity($child_guid); if ($newentity_cache) { $newentity_cache->delete($child_guid); } } } } if ($page->delete()) { system_message(elgg_echo('pages:delete:success')); if ($parent) { if ($parent = get_entity($parent)) { forward($parent->getURL()); } } if (elgg_instanceof($container, 'group')) { forward("pages/group/{$container->guid}/all");
$admin_output = $output; $admin_output[] = $admin->name; $admin_output[] = $admin->email; $admin_output[] = $admin->getURL(); // write to file fwrite($fh, "\"" . implode("\";\"", $admin_output) . "\"" . PHP_EOL); // cache cleanup _elgg_invalidate_cache_for_entity($admin->getGUID()); } } } else { // write to file fwrite($fh, "\"" . implode("\";\"", $output) . "\"" . PHP_EOL); } // cache cleanup _elgg_invalidate_cache_for_entity($subsite->getGUID()); } // read the csv in to a var before output $contents = ""; rewind($fh); while (!feof($fh)) { $contents .= fread($fh, 2048); } // cleanup the temp file fclose($fh); // output the csv header("Content-Type: text/csv"); header("Content-Disposition: attachment; filename=\"subsite_admins.csv\""); header("Content-Length: " . strlen($contents)); echo $contents; exit;
$group = get_entity($group_guid); if (!empty($group) && $group instanceof ElggGroup) { // set counters $already = 0; $new = 0; $failure = 0; $options = array("type" => "user", "relationship" => "member_of_site", "relationship_guid" => elgg_get_site_entity()->getGUID(), "inverse_relationship" => true, "limit" => false, "callback" => "group_tools_guid_only_callback"); $user_guids = elgg_get_entities_from_relationship($options); if (!empty($user_guids)) { foreach ($user_guids as $user_guid) { if (!is_group_member($group->getGUID(), $user_guid)) { if (join_group($group->getGUID(), $user_guid)) { $new++; } else { $failure++; } } else { $already++; } // cleanup cache, to be sure _elgg_invalidate_cache_for_entity($user_guid); } } system_message(elgg_echo("group_tools:action:fix_auto_join:success", array($new, $already, $failure))); } else { register_error(elgg_echo("group_tools:action:error:entity")); } } else { register_error(elgg_echo("group_tools:action:error:input")); } forward(REFERER);
} else { $value = $data[$col_id]; } if (!empty($value)) { if (is_array($value)) { foreach ($value as $v) { create_metadata($user->getGUID(), $metadata_name, $v, "text", $user->getGUID(), ACCESS_PRIVATE, true, $site_guid); } } else { create_metadata($user->getGUID(), $metadata_name, $value, "text", $user->getGUID(), ACCESS_PRIVATE, false, $site_guid); } } } } // cache cleanup _elgg_invalidate_cache_for_entity($user->getGUID()); } } } // done with importing, so unset flag $SUBSITE_MANAGER_IMPORTING_USERS = false; // restore hidden users access_show_hidden_entities($hidden); if (!empty($users_already) || !empty($users_created)) { unset($_SESSION["subsite_manager_import"]); unlink($csv_location); $forward_url = elgg_get_site_url() . "admin/users/import"; system_message(sprintf(elgg_echo("subsite_manager:action:import:step2:success"), $users_created, $users_already)); } else { register_error(elgg_echo("subsite_manager:action:import:step2:error:unknown")); }
/** * Invalidate this class's entry in the cache. * * @param int $guid The entity guid * * @return void * @access private * @deprecated 1.8 */ function invalidate_cache_for_entity($guid) { elgg_deprecated_notice('invalidate_cache_for_entity() is a private function and should not be used.', 1.8); _elgg_invalidate_cache_for_entity($guid); }
/** * Cache an entity. * * Stores an entity in $ENTITY_CACHE; * * @param \ElggEntity $entity Entity to cache * * @return void * @see _elgg_retrieve_cached_entity() * @see _elgg_invalidate_cache_for_entity() * @access private * @todo Use an \ElggCache object */ function _elgg_cache_entity(\ElggEntity $entity) { global $ENTITY_CACHE, $ENTITY_CACHE_DISABLED_GUIDS; // Don't cache non-plugin entities while access control is off, otherwise they could be // exposed to users who shouldn't see them when control is re-enabled. if (!$entity instanceof \ElggPlugin && elgg_get_ignore_access()) { return; } $guid = $entity->getGUID(); if (isset($ENTITY_CACHE_DISABLED_GUIDS[$guid])) { return; } // Don't store too many or we'll have memory problems // @todo Pick a less arbitrary limit if (count($ENTITY_CACHE) > 256) { _elgg_invalidate_cache_for_entity(array_rand($ENTITY_CACHE)); } $ENTITY_CACHE[$guid] = $entity; }
/** * Move an entity to a new site (can anly be call by subsite_manager_move_group_to_site()) * * @param ElggEntity $entity the entity to move * @param ElggSite $target_site the target site * @param array $access_conversion array with group and site access levels * * @access private * * @return bool */ function subsite_manager_move_entity_to_site(ElggEntity $entity, ElggSite $target_site, array $access_conversion) { static $newentity_cache; $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); if (!isset($backtrace[1])) { return false; } $function = elgg_extract("function", $backtrace[1]); if (empty($function) || !in_array($function, array("subsite_manager_move_group_to_site", "subsite_manager_move_entity_to_site"))) { // because this is a dangerous function only allow it to be called the correct way return false; } if (empty($entity) || !$entity instanceof ElggEntity) { return false; } if (empty($target_site) || !elgg_instanceof($target_site, "site")) { return false; } if ($entity->site_guid == $target_site->getGUID()) { return false; } // check for access conversion rules if (empty($access_conversion) || !is_array($access_conversion)) { return false; } $group_acl = (int) elgg_extract("group_acl", $access_conversion); if (empty($group_acl)) { return false; } $old_site_acl = (int) elgg_extract("site_acl", $access_conversion); $affected_access = array(ACCESS_PUBLIC, ACCESS_LOGGED_IN); if (!empty($old_site_acl)) { $affected_access[] = $old_site_acl; } // ignore access and show hidden entities $ia = elgg_set_ignore_access(true); $hidden = access_get_show_hidden_status(); access_show_hidden_entities(true); // first move sub entities (eg blogs in group, event registrations, etc) $options = array("type" => "object", "container_guid" => $entity->getGUID(), "limit" => false); $batch = new ElggBatch("elgg_get_entities", $options); $batch->setIncrementOffset(false); foreach ($batch as $sub_entity) { if (!subsite_manager_move_entity_to_site($sub_entity, $target_site, $access_conversion)) { elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } } // also move owned (sub) entities $options = array("type" => "object", "owner_guid" => $entity->getGUID(), "wheres" => array("(e.guid <> {$entity->getGUID()})"), "limit" => false); $batch = new ElggBatch("elgg_get_entities", $options); $batch->setIncrementOffset(false); foreach ($batch as $sub_entity) { if (!subsite_manager_move_entity_to_site($sub_entity, $target_site, $access_conversion)) { elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } } $dbprefix = elgg_get_config("dbprefix"); // move access collections $query = "UPDATE {$dbprefix}access_collections"; $query .= " SET site_guid = {$target_site->getGUID()}"; $query .= " WHERE owner_guid = {$entity->getGUID()}"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager move entity({$entity->getGUID()}) access collections: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // move annotations $query = "UPDATE {$dbprefix}annotations"; $query .= " SET site_guid = {$target_site->getGUID()}"; $query .= " WHERE entity_guid = {$entity->getGUID()}"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager move entity({$entity->getGUID()}) annotations: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // change annotation access $query = "UPDATE {$dbprefix}annotations"; $query .= " SET access_id = {$group_acl}"; $query .= " WHERE entity_guid = {$entity->getGUID()}"; $query .= " AND access_id IN (" . implode(", ", $affected_access) . ")"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager change entity({$entity->getGUID()}) annotation access: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // move river $query = "UPDATE {$dbprefix}river"; $query .= " SET site_guid = {$target_site->getGUID()}"; $query .= " WHERE subject_guid = {$entity->getGUID()}"; $query .= " OR object_guid = {$entity->getGUID()}"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager move entity({$entity->getGUID()}) river: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // change river access $query = "UPDATE {$dbprefix}river"; $query .= " SET access_id = {$group_acl}"; $query .= " WHERE (subject_guid = {$entity->getGUID()}"; $query .= " OR object_guid = {$entity->getGUID()})"; $query .= " AND access_id IN (" . implode(", ", $affected_access) . ")"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager change entity({$entity->getGUID()}) river access: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // move metadata $query = "UPDATE {$dbprefix}metadata"; $query .= " SET site_guid = {$target_site->getGUID()}"; $query .= " WHERE entity_guid = {$entity->getGUID()}"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager move entity({$entity->getGUID()}) metadata: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // change metadata access $query = "UPDATE {$dbprefix}metadata"; $query .= " SET access_id = {$group_acl}"; $query .= " WHERE entity_guid = {$entity->getGUID()}"; $query .= " AND access_id IN (" . implode(", ", $affected_access) . ")"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager change entity({$entity->getGUID()}) metadata access: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // move entity $query = "UPDATE {$dbprefix}entities"; $query .= " SET site_guid = {$target_site->getGUID()}"; $query .= " WHERE guid = {$entity->getGUID()}"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager move entity({$entity->getGUID()}) entity: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // change entity access $query = "UPDATE {$dbprefix}entities"; $query .= " SET access_id = {$group_acl}"; $query .= " WHERE guid = {$entity->getGUID()}"; $query .= " AND access_id IN (" . implode(", ", $affected_access) . ")"; try { update_data($query); } catch (Exception $e) { elgg_log("Subsite manager change entity({$entity->getGUID()}) entity access: " . $e->getMessage(), "ERROR"); elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return false; } // cache cleanup _elgg_invalidate_cache_for_entity($entity->getGUID()); if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $newentity_cache->delete($entity->getGUID()); } elgg_set_ignore_access($ia); access_show_hidden_entities($hidden); return true; }
/** * Sent out the notifications for the provided annotation_id * * @param int $id the id of the annotation * @param string $event the type of event * * @return void */ function advanced_notifications_annotation_notification($id, $event) { global $NOTIFICATION_HANDLERS; // get the annotation $annotation = elgg_get_annotation_from_id($id); if (!empty($annotation)) { // are notifications on this annotation allowed if (advanced_notifications_is_registered_notification_annotation($annotation)) { // get the entity the annotation was made on $entity = $annotation->getEntity(); // get the owner of the annotation $owner = $annotation->getOwnerEntity(); if (!empty($entity) && !empty($owner)) { // make sure the entity isn't a PRIVATE entity, this shouldn't happed as the commandline shouldn't be called if ($entity->access_id != ACCESS_PRIVATE) { // is the entity a registered entity type/subtype, this shouldn't happen see above $default_subject = advanced_notifications_is_registered_notification_entity($entity, true); if (!empty($default_subject)) { // prepare the message to sent $default_message = $default_subject . ": " . $entity->getURL(); // check if we need to disable site notifications if (elgg_get_plugin_setting("replace_site_notifications", "advanced_notifications") == "yes") { unregister_notification_handler("site"); } if (!empty($NOTIFICATION_HANDLERS) && is_array($NOTIFICATION_HANDLERS)) { // this could take a long time, especialy with large groups set_time_limit(0); // prepare options to get the interested users $options = array("type" => "user", "site_guids" => ELGG_ENTITIES_ANY_VALUE, "limit" => false, "joins" => array("JOIN " . elgg_get_config("dbprefix") . "users_entity ue ON e.guid = ue.guid"), "wheres" => array("(ue.banned = 'no')", "(e.guid <> " . $owner->getGUID() . ")"), "relationship_guid" => $entity->getContainerGUID(), "inverse_relationship" => true, "callback" => "advanced_notifications_row_to_guid"); foreach ($NOTIFICATION_HANDLERS as $method => $dummy) { // get the interested users for the entity $options["relationship"] = "notify" . $method; // allow the interested user options to be ajusted $params = array("annotation" => $annotation, "entity" => $entity, "options" => $options, "method" => $method); $options = elgg_trigger_plugin_hook("interested_users:options", "notify:" . $method, $params, $options); if (!empty($options)) { // we got through the hook, so get the users $user_guids = elgg_get_entities_from_relationship($options); if (!empty($user_guids)) { // process each user foreach ($user_guids as $user_guid) { // fetch the user entity to process $user = get_user($user_guid); if (!empty($user)) { // check if the user has access to the entity if (has_access_to_entity($entity, $user)) { // trigger a hook to make a custom message $message = elgg_trigger_plugin_hook("notify:annotation:message", $annotation->getSubtype(), array("annotation" => $annotation, "to_entity" => $user, "method" => $method), $default_message); // check if the hook made a correct message if (empty($message) && $message !== false) { // the hook did it incorrect, so reset the message $message = $default_message; } // this is new, trigger a hook to make a custom subject $subject = elgg_trigger_plugin_hook("notify:annotation:subject", $annotation->getSubtype(), array("annotation" => $annotation, "to_entity" => $user, "method" => $method), $default_subject); // check if the hook made a correct subject if (empty($subject)) { // the hook did it incorrect, so reset the subject $subject = $default_subject; } // if the hook returnd false, don't sent a notification if ($message !== false) { notify_user($user->getGUID(), $entity->getContainerGUID(), $subject, $message, null, $method); } } } // cleanup some of the caches _elgg_invalidate_query_cache(); _elgg_invalidate_cache_for_entity($user_guid); unset($user); } } // some small cleanup unset($user_guids); } } } } } } } } }
/** * Get page components to list all site podcasts with at least one episode * * @param int $container_guid The GUID of the page owner or NULL for all podcasts * * @return array */ function podcasts_get_page_content_list_podcasts($container_guid = NULL) { $return = array(); $return['filter_context'] = 'all_podcasts'; // Options to grab users/groups $options = array('types' => array('user', 'group'), 'full_view' => false, 'podcast_list_class' => 'elgg-list', 'podcast_item_class' => 'elgg-item elgg-podcast'); // Build query to get users/groups with at least one podcast entity $dbprefix = elgg_get_config('dbprefix'); $subtype_id = get_subtype_id('object', 'podcast'); $options['selects'][] = "(SELECT COUNT(*) from {$dbprefix}entities es where es.container_guid = e.guid AND ((es.type = 'object' AND es.subtype IN ({$subtype_id})))) as episode_count"; $options['joins'][] = "JOIN {$dbprefix}users_entity ue"; $options['wheres'][] = "ue.banned = 'no'"; $options['wheres'][] = "(exists (SELECT 1 FROM {$dbprefix}entities p WHERE p.container_guid = e.guid AND (p.type = 'object' AND p.subtype IN ({$subtype_id}))))"; $options['order_by'] = "episode_count DESC"; $options['group_by'] = 'e.guid HAVING episode_count >= 1'; // Clear current users entity cache _elgg_invalidate_cache_for_entity(elgg_get_logged_in_user_guid()); $list = elgg_list_entities($options, 'elgg_get_entities', 'podcasts_list'); if ($list) { $return['content'] = $list; } else { if (elgg_get_viewtype() == 'default') { $return['content'] = elgg_echo('podcasts:none'); } } elgg_register_title_button(); $return['title'] = elgg_echo('podcasts:title:allpodcasts'); return $return; }
/** * Removes user $guid's admin flag. * * @param int $user_guid User GUID * @return bool */ public function removeAdmin($user_guid) { $user = get_entity($user_guid); if (!$user instanceof ElggUser || !$user->canEdit()) { return false; } if (!$this->events->trigger('remove_admin', 'user', $user)) { return false; } $query = "\n\t\t\tUPDATE {$this->table}\n\t\t\tSET admin = 'no'\n\t\t\tWHERE guid = :guid\n\t\t"; $params = [':guid' => (int) $user_guid]; _elgg_invalidate_cache_for_entity($user_guid); _elgg_invalidate_memcache_for_entity($user_guid); if ($this->db->updateData($query, true, $params)) { return true; } return false; }
// Update site settings error_log("[elgg_copy] Updating dataroot and path"); update_data("UPDATE {$dbprefix}datalists SET value = '{$dataroot}' where name = 'dataroot'"); update_data("UPDATE {$dbprefix}datalists SET value = '{$path}' where name = 'path'"); update_data("UPDATE {$dbprefix}sites_entity SET url = '{$url}' where guid = 1"); update_data("UPDATE {$dbprefix}metastrings SET string = '{$dataroot}'\nWHERE id = (\n SELECT value_id\n FROM {$dbprefix}metadata\n WHERE name_id = (\n SELECT *\n FROM (\n SELECT id\n FROM {$dbprefix}metastrings\n WHERE string = 'filestore::dir_root'\n ) as ms2\n )\n LIMIT 1\n)"); // turn off https login if necessary if (strpos($url, 'https') === false) { update_data("UPDATE {$dbprefix}config SET value = 'i:0;' where name = 'https_login'"); } } // Invalidate cache error_log("[elgg_copy] Invalidating cache"); elgg_invalidate_simplecache(); elgg_reset_system_cache(); _elgg_invalidate_cache_for_entity($elgg_copy_plugin->guid); _elgg_invalidate_memcache_for_entity($elgg_copy_plugin->guid); _elgg_disable_caching_for_entity($elgg_copy_plugin->guid); // unset plugins cache elgg_set_config('plugins_by_id_map', array()); // regenerate plugin entities error_log("[elgg_copy] Regenerating plugin entities"); _elgg_generate_plugin_entities(); // Update the sandbox settings error_log("[elgg_copy] Updating elgg_copy plugin settings"); elgg_set_plugin_setting('master_url', $master_url, PLUGIN_ID); elgg_set_plugin_setting('master_request_key', $master_request_key, PLUGIN_ID); elgg_set_plugin_setting('request_key', $key, PLUGIN_ID); elgg_set_plugin_setting('enable_plugins', $enable_plugins, PLUGIN_ID); elgg_set_plugin_setting('update_mod', $update_mod, PLUGIN_ID); elgg_set_plugin_setting('mysqldump_path', $mysqldump_path, PLUGIN_ID);
/** * 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; } if (!elgg_trigger_event('delete', $this->type, $this)) { return false; } if (!$this->canEdit()) { 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) { // Temporary token overriding access controls // @todo Do this better. static $__RECURSIVE_DELETE_TOKEN; // Make it slightly harder to guess $__RECURSIVE_DELETE_TOKEN = md5(elgg_get_logged_in_user_guid()); $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); $__RECURSIVE_DELETE_TOKEN = null; 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(); 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}"); } } return (bool) $res; }
/** * Delete an entity. * * Removes an entity and its metadata, annotations, relationships, river entries, * and private data. * * Optionally can remove entities contained and owned by $guid. * * @tip Use ElggEntity::delete() instead. * * @warning If deleting recursively, this bypasses ownership of items contained by * the entity. That means that if the container_guid = $guid, the item will be deleted * regardless of who owns it. * * @param int $guid The guid of the entity to delete * @param bool $recursive If true (default) then all entities which are * owned or contained by $guid will also be deleted. * * @return bool * @access private */ function delete_entity($guid, $recursive = true) { global $CONFIG, $ENTITY_CACHE; $guid = (int) $guid; if ($entity = get_entity($guid)) { if (elgg_trigger_event('delete', $entity->type, $entity)) { if ($entity->canEdit()) { // delete cache if (isset($ENTITY_CACHE[$guid])) { _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) { // Temporary token overriding access controls // @todo Do this better. static $__RECURSIVE_DELETE_TOKEN; // Make it slightly harder to guess $__RECURSIVE_DELETE_TOKEN = md5(elgg_get_logged_in_user_guid()); $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("limit" => 0, "order_by" => false, "site_guids" => false); foreach (array("site_guid", "container_guid", "owner_guid") as $column) { $options['wheres'] = array("(({$column} = {$guid}) AND guid != {$guid})"); $batch = new ElggBatch('elgg_get_entities', $options); $batch->setIncrementOffset(false); foreach ($batch as $e) { $e->delete(true); } } access_show_hidden_entities($entity_disable_override); $__RECURSIVE_DELETE_TOKEN = null; elgg_set_ignore_access($ia); } // Now delete the entity itself $entity->deleteMetadata(); $entity->deleteOwnedMetadata(); $entity->deleteAnnotations(); $entity->deleteOwnedAnnotations(); $entity->deleteRelationships(); elgg_delete_river(array('subject_guid' => $guid)); elgg_delete_river(array('object_guid' => $guid)); remove_all_private_settings($guid); $res = delete_data("DELETE from {$CONFIG->dbprefix}entities where guid={$guid}"); if ($res) { $sub_table = ""; // Where appropriate delete the sub table switch ($entity->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) { delete_data("DELETE from {$sub_table} where guid={$guid}"); } } return (bool) $res; } } } return false; }
/** * Removes user $guid's admin flag. * * @param int $user_guid User GUID * * @return bool */ function remove_user_admin($user_guid) { global $CONFIG; $user = get_entity((int) $user_guid); if ($user && $user instanceof ElggUser && $user->canEdit()) { if (elgg_trigger_event('remove_admin', 'user', $user)) { // invalidate memcache for this user static $newentity_cache; if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $newentity_cache->delete($user_guid); } $r = update_data("UPDATE {$CONFIG->dbprefix}users_entity set admin='no' where guid={$user_guid}"); _elgg_invalidate_cache_for_entity($user_guid); return $r; } return FALSE; } return FALSE; }
/** * Get a page selector for in widgets * * @param ElggEntity $container the container to get the pages for * @param int $depth used for indentation * * @return array|false */ function theme_haarlem_pages_get_widget_selector(ElggEntity $container, $depth = 0) { if (empty($container) || !elgg_instanceof($container)) { return false; } if ($depth == 0) { $ordered = elgg_get_entities(array('type' => 'object', 'subtype' => 'page_top', 'container_guid' => $container->getGUID(), 'limit' => false)); } else { $ordered = elgg_get_entities_from_metadata(array('type' => 'object', 'subtype' => 'page', 'metadata_name' => 'parent_guid', 'metadata_value' => $container->getGUID(), 'limit' => false)); } if (empty($ordered)) { return false; } $result = array(); foreach ($ordered as $order => $page) { // add this page $result[$page->getGUID()] = trim(str_repeat('-', $depth) . ' ' . $page->title); // invalidate cache for OOM // @todo find a better way for this _elgg_invalidate_cache_for_entity($page->getGUID()); // append children $children = theme_haarlem_pages_get_widget_selector($page, $depth + 1); if (!empty($children)) { $result += $children; unset($children); } } unset($ordered); return $result; }
/** * 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; }
public function testElggBatchDeleteHandlesBrokenEntities() { $num_test_entities = 8; $guids = array(); for ($i = $num_test_entities; $i > 0; $i--) { $entity = new \ElggObject(); $entity->type = 'object'; $entity->subtype = 'test_5357_subtype'; $entity->access_id = ACCESS_PUBLIC; $entity->save(); $guids[] = $entity->guid; _elgg_invalidate_cache_for_entity($entity->guid); } // break entities such that the first fetch has one incomplete // and the second and third fetches have only incompletes! $db_prefix = elgg_get_config('dbprefix'); delete_data("\n\t\t\tDELETE FROM {$db_prefix}objects_entity\n\t\t\tWHERE guid IN ({$guids[1]}, {$guids[2]}, {$guids[3]}, {$guids[4]}, {$guids[5]})\n\t\t"); $options = array('type' => 'object', 'subtype' => 'test_5357_subtype', 'order_by' => 'e.guid'); $entities_visited = array(); $batch = new \ElggBatch('elgg_get_entities', $options, null, 2, false); /* @var \ElggEntity[] $batch */ foreach ($batch as $entity) { $entities_visited[] = $entity->guid; $entity->delete(); } // The broken entities should not have been visited $this->assertEqual($entities_visited, array($guids[0], $guids[6], $guids[7])); // cleanup (including leftovers from previous tests) $entity_rows = elgg_get_entities(array_merge($options, array('callback' => '', 'limit' => false))); $guids = array(); foreach ($entity_rows as $row) { $guids[] = $row->guid; } delete_data("DELETE FROM {$db_prefix}entities WHERE guid IN (" . implode(',', $guids) . ")"); delete_data("DELETE FROM {$db_prefix}objects_entity WHERE guid IN (" . implode(',', $guids) . ")"); }
/** * 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; }
/** * Removes user $guid's admin flag. * * @param int $user_guid User GUID * * @return bool */ function removeAdmin($user_guid) { $user = get_entity((int) $user_guid); if ($user && $user instanceof \ElggUser && $user->canEdit()) { if (_elgg_services()->events->trigger('remove_admin', 'user', $user)) { // invalidate memcache for this user static $newentity_cache; if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new \ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $newentity_cache->delete($user_guid); } $r = _elgg_services()->db->updateData("UPDATE {$this->CONFIG->dbprefix}users_entity set admin='no' where guid={$user_guid}"); _elgg_invalidate_cache_for_entity($user_guid); return $r; } return false; } return false; }
public function test_update_handlers_can_change_attributes() { $object = new \ElggObject(); $object->subtype = 'issue6225'; $object->access_id = ACCESS_PUBLIC; $object->save(); $guid = $object->guid; elgg_register_event_handler('update', 'object', array('\\ElggCoreRegressionBugsTest', 'handleUpdateForIssue6225test')); $object->save(); elgg_unregister_event_handler('update', 'object', array('\\ElggCoreRegressionBugsTest', 'handleUpdateForIssue6225test')); _elgg_invalidate_cache_for_entity($guid); $object = get_entity($guid); $this->assertEqual($object->access_id, ACCESS_PRIVATE); $object->delete(); }
/** * Disables all entities owned and contained by a user (or another entity) * * @param int $owner_guid The owner GUID * @return bool */ public function disableEntities($owner_guid) { $entity = get_entity($owner_guid); if (!$entity || !$entity->canEdit()) { return false; } if (!$this->events->trigger('disable', $entity->type, $entity)) { return false; } $query = "\n\t\t\tUPDATE {$this->table}entities\n\t\t\tSET enabled='no'\n\t\t\tWHERE owner_guid = :owner_guid\n\t\t\tOR container_guid = :owner_guid"; $params = [':owner_guid' => (int) $owner_guid]; _elgg_invalidate_cache_for_entity($entity->guid); _elgg_invalidate_memcache_for_entity($entity->guid); if ($this->db->updateData($query, true, $params)) { return true; } return false; }