/** * Invalidate an entity in memcache * * @param int $entity_guid The GUID of the entity to invalidate * * @return void * @access private */ function _elgg_invalidate_memcache_for_entity($entity_guid) { static $newentity_cache; if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new \ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $newentity_cache->delete($entity_guid); } }
/** *function to update the metadata *same as the update_metadata, only made metadata editable */ function izap_update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id) { $id = (int) $id; if (!($md = elgg_get_metadata_from_id($id))) { return false; } // If memcached then we invalidate the cache for this entry static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = elgg_get_logged_in_user_guid(); } $access_id = (int) $access_id; // Support boolean types (as integers) if (is_bool($value)) { if ($value) { $value = 1; } else { $value = 0; } } // Add the metastring $value = elgg_get_metastring_id($value); if (!$value) { return false; } $name = elgg_get_metastring_id($name); if (!$name) { return false; } // If ok then add it $db_prefix = elgg_get_config('dbprefix'); $result = update_data("UPDATE {$db_prefix}metadata set value_id='{$value}', value_type='{$value_type}', access_id={$access_id}, owner_guid={$owner_guid} where id={$id} and name_id='{$name}'"); if ($result !== false) { $obj = elgg_get_metadata_from_id($id); if (elgg_trigger_event('update', 'metadata', $obj)) { return true; } else { elgg_delete_metadata(array('metadata_id' => $id)); } } return $result; }
public function set($name, $value) { if (is_array($value)) { if (empty($value)) { $value = null; } else { $value = json_encode($value); } } if (parent::set($name, $value)) { $this->settings_cache[$name] = $value; // 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($this->getGUID()); } } }
/** * 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}"); invalidate_cache_for_entity($user_guid); return $r; } return FALSE; } return FALSE; }
/** * Delete any orphaned entries in metastrings. This is run by the garbage collector. * */ function delete_orphaned_metastrings() { global $CONFIG; // If memcache is enabled then we need to flush it of deleted values if (is_memcache_available()) { $select_query = "\n\t\t\tSELECT * \n\t\t\tfrom {$CONFIG->dbprefix}metastrings where \n\t\t\t( \n\t\t\t\t(id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND \n\t\t\t\t(id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND \n\t\t\t\t(id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND \n\t\t\t\t(id not in (select value_id from {$CONFIG->dbprefix}annotations)) \n\t\t\t)"; $dead = get_data($select_query); if ($dead) { static $metastrings_memcache; if (!$metastrings_memcache) { $metastrings_memcache = new ElggMemcache('metastrings_memcache'); } foreach ($dead as $d) { $metastrings_memcache->delete($d->string); } } } $query = "\n\t\t\tDELETE \n\t\t\tfrom {$CONFIG->dbprefix}metastrings where \n\t\t\t( \n\t\t\t\t(id not in (select name_id from {$CONFIG->dbprefix}metadata)) AND \n\t\t\t\t(id not in (select value_id from {$CONFIG->dbprefix}metadata)) AND \n\t\t\t\t(id not in (select name_id from {$CONFIG->dbprefix}annotations)) AND \n\t\t\t\t(id not in (select value_id from {$CONFIG->dbprefix}annotations)) \n\t\t\t)"; return delete_data($query); }
/** * Update an entity in the database. * * There are 4 basic entity types: site, user, object, and group. * All entities are split between two tables: the entities table and their type table. * * @warning Plugin authors should never call this directly. Use ->save() instead. * * @param int $guid The guid of the entity to update * @param int $owner_guid The new owner guid * @param int $access_id The new access id * @param int $container_guid The new container guid * @param int $time_created The time creation timestamp * * @return bool * @link http://docs.elgg.org/DataModel/Entities * @access private */ function update_entity($guid, $owner_guid, $access_id, $container_guid = null, $time_created = null) { global $CONFIG, $ENTITY_CACHE; $guid = (int) $guid; $owner_guid = (int) $owner_guid; $access_id = (int) $access_id; $container_guid = (int) $container_guid; if (is_null($container_guid)) { $container_guid = $owner_guid; } $time = time(); $entity = get_entity($guid); if ($time_created == null) { $time_created = $entity->time_created; } else { $time_created = (int) $time_created; } if ($entity && $entity->canEdit()) { if (elgg_trigger_event('update', $entity->type, $entity)) { $ret = update_data("UPDATE {$CONFIG->dbprefix}entities\n\t\t\t\tset owner_guid='{$owner_guid}', access_id='{$access_id}',\n\t\t\t\tcontainer_guid='{$container_guid}', time_created='{$time_created}',\n\t\t\t\ttime_updated='{$time}' WHERE guid={$guid}"); if ($entity instanceof ElggObject) { update_river_access_by_object($guid, $access_id); } // 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) { $new_entity = $newentity_cache->delete($guid); } // Handle cases where there was no error BUT no rows were updated! if ($ret === false) { return false; } return true; } } }
/** * Unban a user. * * @param int $user_guid Unban a user. */ function unban_user($user_guid) { global $CONFIG; $user_guid = (int) $user_guid; $user = get_entity($user_guid); if ($user && $user->canEdit() && $user instanceof ElggUser) { if (trigger_elgg_event('unban', 'user', $user)) { create_metadata($user_guid, 'ban_reason', '', '', 0, ACCESS_PUBLIC); // 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); } return update_data("UPDATE {$CONFIG->dbprefix}users_entity set banned='no' where guid={$user_guid}"); } } return false; }
/** * Sets the value for a system-wide piece of data (overwriting a previous value if it exists) * * @param string $name The name of the datalist * @param string $value The new value * @return true */ function datalist_set($name, $value) { global $CONFIG, $DATALIST_CACHE; $name = sanitise_string($name); $value = sanitise_string($value); // If memcache is available then invalidate the cached copy static $datalist_memcache; if (!$datalist_memcache && is_memcache_available()) { $datalist_memcache = new ElggMemcache('datalist_memcache'); } if ($datalist_memcache) { $datalist_memcache->delete($name); } //delete_data("delete from {$CONFIG->dbprefix}datalists where name = '{$name}'"); insert_data("INSERT into {$CONFIG->dbprefix}datalists set name = '{$name}', value = '{$value}' ON DUPLICATE KEY UPDATE value='{$value}'"); $DATALIST_CACHE[$name] = $value; return true; }
/** * The settings of a plugin have changed, check if we need to reset the cron cache file (only on subsites) * * @param string $hook * @param string $action => the action being called * @param unknown_type $return_value * @param unknown_type $params */ function subsite_manager_plugin_action_hook($hook, $action, $return_value, $params) { // are we on a Subsite, so we can handle cron reset if (subsite_manager_on_subsite() && $action == "plugins/settings/save") { $site = elgg_get_site_entity(); // handling of the cron cache reset is done by the event function subsite_manager_remove_cron_cache($site->getGUID()); } // clear plugin order cache if (is_memcache_available()) { $memcache = new ElggMemcache('subsite_manager'); $memcache->delete('plugin_order'); } }
/** * 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; }
/** * Set the value for a datalist element. * * @param string $name The name of the datalist * @param string $value The new value * * @return bool * @access private */ function datalist_set($name, $value) { global $CONFIG, $DATALIST_CACHE; // cannot store anything longer than 255 characters in db, so catch before we set if (elgg_strlen($name) > 255) { elgg_log("The name length for configuration variables cannot be greater than 255", "ERROR"); return false; } $sanitised_name = sanitise_string($name); $sanitised_value = sanitise_string($value); // If memcache is available then invalidate the cached copy static $datalist_memcache; if (!$datalist_memcache && is_memcache_available()) { $datalist_memcache = new ElggMemcache('datalist_memcache'); } if ($datalist_memcache) { $datalist_memcache->delete($name); } $success = insert_data("INSERT into {$CONFIG->dbprefix}datalists" . " set name = '{$sanitised_name}', value = '{$sanitised_value}'" . " ON DUPLICATE KEY UPDATE value='{$sanitised_value}'"); if ($success !== FALSE) { $DATALIST_CACHE[$name] = $value; return true; } else { return false; } }
/** * 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; }
/** * Delete an item of metadata, where the current user has access. * * @param $id int The item of metadata to delete. */ function delete_metadata($id) { global $CONFIG; $id = (int) $id; $metadata = get_metadata($id); // Tidy up if memcache is enabled. static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { $metabyname_memcache->delete("{$metadata->entity_guid}:{$metadata->name_id}"); } if ($metadata->canEdit()) { return delete_data("DELETE from {$CONFIG->dbprefix}metadata where id={$id}"); } }
/** * Update a specific piece of metadata. * * @param int $id ID of the metadata to update * @param string $name Metadata name * @param string $value Metadata value * @param string $value_type Value type * @param int $owner_guid Owner guid * @param int $access_id Access ID * * @return bool */ function update($id, $name, $value, $value_type, $owner_guid, $access_id) { $id = (int) $id; if (!($md = $this->get($id))) { return false; } if (!$md->canEdit()) { return false; } // If memcached then we invalidate the cache for this entry static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new \ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { // @todo fix memcache (name_id is not a property of \ElggMetadata) $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } $value_type = detect_extender_valuetype($value, $this->db->sanitizeString(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = $this->session->getLoggedInUserGuid(); } $access_id = (int) $access_id; // Support boolean types (as integers) if (is_bool($value)) { $value = (int) $value; } $value_id = $this->metastringsTable->getId($value); if (!$value_id) { return false; } $name_id = $this->metastringsTable->getId($name); if (!$name_id) { return false; } // If ok then add it $query = "UPDATE {$this->table}" . " set name_id='{$name_id}', value_id='{$value_id}', value_type='{$value_type}', access_id={$access_id}," . " owner_guid={$owner_guid} where id={$id}"; $result = $this->db->updateData($query); if ($result !== false) { $this->cache->save($md->entity_guid, $name, $value); // @todo this event tells you the metadata has been updated, but does not // let you do anything about it. What is needed is a plugin hook before // the update that passes old and new values. $obj = $this->get($id); $this->events->trigger('update', 'metadata', $obj); } return $result; }
/** * Delete any orphaned entries in metastrings. * * @return void */ function garbagecollector_orphaned_metastrings() { $dbprefix = elgg_get_config('dbprefix'); // Garbage collect metastrings echo elgg_echo('garbagecollector:gc:metastrings'); // If memcache is enabled then we need to flush it of deleted values if (is_memcache_available()) { $select_query = "\n\t\tSELECT * FROM {$dbprefix}metastrings WHERE\n\t\t(\n\t\t\t(id NOT IN (SELECT name_id FROM {$dbprefix}metadata)) AND\n\t\t\t(id NOT IN (SELECT value_id FROM {$dbprefix}metadata)) AND\n\t\t\t(id NOT IN (SELECT name_id FROM {$dbprefix}annotations)) AND\n\t\t\t(id NOT IN (SELECT value_id FROM {$dbprefix}annotations))\n\t\t)"; $dead = get_data($select_query); if ($dead) { static $metastrings_memcache; if (!$metastrings_memcache) { $metastrings_memcache = new \ElggMemcache('metastrings_memcache'); } foreach ($dead as $d) { $metastrings_memcache->delete($d->string); } } } $query = "\n\t\tDELETE FROM {$dbprefix}metastrings WHERE\n\t\t(\n\t\t\t(id NOT IN (SELECT name_id FROM {$dbprefix}metadata)) AND\n\t\t\t(id NOT IN (SELECT value_id FROM {$dbprefix}metadata)) AND\n\t\t\t(id NOT IN (SELECT name_id FROM {$dbprefix}annotations)) AND\n\t\t\t(id NOT IN (SELECT value_id FROM {$dbprefix}annotations))\n\t\t)"; $result = delete_data($query); if ($result !== false) { echo elgg_echo('garbagecollector:ok'); } else { echo elgg_echo('garbagecollector:error'); } }
/** * Deletes all private settings for an entity. * * @param int $entity_guid The Entity GUID * * @return bool * @see get_private_setting() * @see get_all_private_settings() * @see set_private_setting() * @see remove_private_settings() * @link http://docs.elgg.org/DataModel/Entities/PrivateSettings */ function remove_all_private_settings($entity_guid) { global $PRIVATE_SETTINGS_CACHE; static $private_setting_memcache; $dbprefix = elgg_get_config("dbprefix"); $entity_guid = (int) $entity_guid; // check if you have access to the entity if (!get_entity_as_row($entity_guid)) { return false; } if (!isset($private_setting_memcache) && is_memcache_available()) { $private_setting_memcache = new ElggMemcache("private_settings"); } $query = "DELETE FROM {$dbprefix}private_settings"; $query .= " WHERE entity_guid = {$entity_guid}"; $result = delete_data($query); if ($result !== false) { // unset local cache if (isset($PRIVATE_SETTINGS_CACHE[$entity_guid])) { unset($PRIVATE_SETTINGS_CACHE[$entity_guid]); } // unset memcache if ($private_setting_memcache) { // invalidate the settings in Memcache $private_setting_memcache->delete($entity_guid); } } return $result !== false; }
/** * Removes all settings for this plugin. * * @todo Should be a better way to do this without dropping to raw SQL. * @todo If we could namespace the plugin settings this would be cleaner. * @return bool */ public function unsetAllSettings() { $db_prefix = get_config('dbprefix'); $ps_prefix = elgg_namespace_plugin_private_setting('internal', ''); $q = "DELETE FROM {$db_prefix}private_settings\n\t\t\tWHERE entity_guid = {$this->guid}\n\t\t\tAND name NOT LIKE '{$ps_prefix}%'\n\t\t\tAND name <> 'path'"; $result = delete_data($q); // check memcache if ($result !== false && is_memcache_available()) { $private_setting_cache = new ElggMemcache("private_settings"); // remove settings from memcache $private_setting_cache->delete($this->guid); } // unvalidate cache to reset to default behaviour elgg_invalidate_simplecache(); return $result; }
/** * Deletes a metastring-based object by its id * * @param int $id The object's ID * @param string $type The object's metastring type: annotation or metadata * @return bool * * @since 1.8.0 * @access private */ function elgg_delete_metastring_based_object_by_id($id, $type) { $id = (int) $id; $db_prefix = elgg_get_config('dbprefix'); switch ($type) { case 'annotation': case 'annotations': $type = 'annotations'; break; case 'metadata': $type = 'metadata'; break; default: return false; } $obj = elgg_get_metastring_based_object_from_id($id, $type); $table = $db_prefix . $type; if ($obj) { // Tidy up if memcache is enabled. // @todo only metadata is supported if ($type == 'metadata') { static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { $metabyname_memcache->delete("{$obj->entity_guid}:{$obj->name_id}"); } } if ($obj->canEdit() && elgg_trigger_event('delete', $type, $obj)) { return delete_data("DELETE from {$table} where id={$id}"); } } return false; }
/** * 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])) { 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); $sub_entities = get_data("SELECT * from {$CONFIG->dbprefix}entities\n\t\t\t\t\t\tWHERE container_guid={$guid}\n\t\t\t\t\t\t\tor owner_guid={$guid}\n\t\t\t\t\t\t\tor site_guid={$guid}", 'entity_row_to_elggstar'); if ($sub_entities) { foreach ($sub_entities as $e) { // check for equality so that an entity that is its own // owner or container does not cause infinite loop if ($e->guid != $guid) { $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 $res; } } } return false; }
public function invalidate($key) { $this->memcache->delete($key); }
/** * Low level function to reset a given user's password. * * This can only be called from execute_new_password_request(). * * @param int $user_guid The user. * @param string $password Text (which will then be converted into a hash and stored) * * @return bool */ function force_user_password_reset($user_guid, $password) { global $CONFIG; $user = get_entity($user_guid); if ($user instanceof ElggUser) { $salt = generate_random_cleartext_password(); // Reset the salt $user->salt = $salt; $hash = generate_user_password($user, $password); $query = "UPDATE {$CONFIG->dbprefix}users_entity\n\t\t\tset password='******', salt='{$salt}' where guid={$user_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($user_guid); } return update_data($query); } return false; }
/** * 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 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; }
/** * 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; }
/** * Update a specific piece of metadata. * * @param int $id ID of the metadata to update * @param string $name Metadata name * @param string $value Metadata value * @param string $value_type Value type * @param int $owner_guid Owner guid * @param int $access_id Access ID * * @return bool */ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id) { global $CONFIG; $id = (int) $id; if (!($md = elgg_get_metadata_from_id($id))) { return false; } if (!$md->canEdit()) { return false; } // If memcached then we invalidate the cache for this entry static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = elgg_get_logged_in_user_guid(); } $access_id = (int) $access_id; $access = get_access_sql_suffix(); // Support boolean types (as integers) if (is_bool($value)) { if ($value) { $value = 1; } else { $value = 0; } } // Add the metastring $value = add_metastring($value); if (!$value) { return false; } $name = add_metastring($name); if (!$name) { return false; } // If ok then add it $query = "UPDATE {$CONFIG->dbprefix}metadata" . " set name_id='{$name}', value_id='{$value}', value_type='{$value_type}', access_id={$access_id}," . " owner_guid={$owner_guid} where id={$id}"; $result = update_data($query); if ($result !== false) { $obj = elgg_get_metadata_from_id($id); if (elgg_trigger_event('update', 'metadata', $obj)) { return true; } else { elgg_delete_metadata_by_id($id); } } return $result; }
/** * Update a specific piece of metadata. * * @param int $id ID of the metadata to update * @param string $name Metadata name * @param string $value Metadata value * @param string $value_type Value type * @param int $owner_guid Owner guid * @param int $access_id Access ID * * @return bool */ function update_metadata($id, $name, $value, $value_type, $owner_guid, $access_id) { global $CONFIG; $id = (int) $id; if (!($md = elgg_get_metadata_from_id($id))) { return false; } if (!$md->canEdit()) { return false; } // If memcached then we invalidate the cache for this entry static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { // @todo fix memcache (name_id is not a property of ElggMetadata) $metabyname_memcache->delete("{$md->entity_guid}:{$md->name_id}"); } $value_type = detect_extender_valuetype($value, sanitise_string(trim($value_type))); $owner_guid = (int) $owner_guid; if ($owner_guid == 0) { $owner_guid = elgg_get_logged_in_user_guid(); } $access_id = (int) $access_id; // Support boolean types (as integers) if (is_bool($value)) { $value = (int) $value; } $value_id = elgg_get_metastring_id($value); if (!$value_id) { return false; } $name_id = elgg_get_metastring_id($name); if (!$name_id) { return false; } // If ok then add it $query = "UPDATE {$CONFIG->dbprefix}metadata" . " set name_id='{$name_id}', value_id='{$value_id}', value_type='{$value_type}', access_id={$access_id}," . " owner_guid={$owner_guid} where id={$id}"; $result = update_data($query); if ($result !== false) { _elgg_get_metadata_cache()->save($md->entity_guid, $name, $value); // @todo this event tells you the metadata has been updated, but does not // let you do anything about it. What is needed is a plugin hook before // the update that passes old and new values. $obj = elgg_get_metadata_from_id($id); elgg_trigger_event('update', 'metadata', $obj); } return $result; }
/** * Deletes a metastring-based object by its id * * @param int $id The object's ID * @param string $type The object's metastring type: annotation or metadata * @return bool * @access private */ function _elgg_delete_metastring_based_object_by_id($id, $type) { $id = (int) $id; $db_prefix = elgg_get_config('dbprefix'); switch ($type) { case 'annotations': case 'annotation': $table = $db_prefix . 'annotations'; $type = 'annotation'; break; case 'metadata': $table = $db_prefix . 'metadata'; $type = 'metadata'; break; default: return false; } $obj = _elgg_get_metastring_based_object_from_id($id, $type); if ($obj) { // Tidy up if memcache is enabled. // @todo only metadata is supported if ($type == 'metadata') { static $metabyname_memcache; if (!$metabyname_memcache && is_memcache_available()) { $metabyname_memcache = new \ElggMemcache('metabyname_memcache'); } if ($metabyname_memcache) { // @todo why name_id? is that even populated? $metabyname_memcache->delete("{$obj->entity_guid}:{$obj->name_id}"); } } if ($obj->canEdit()) { // bc code for when we triggered 'delete', 'annotations' #4770 $result = true; if ($type == "annotation") { $result = elgg_trigger_event('delete', 'annotations', $obj); if ($result === false) { elgg_deprecated_notice("Use the event 'delete', 'annotation'", 1.9); } } if (elgg_trigger_event('delete', $type, $obj) && $result) { return (bool) delete_data("DELETE FROM {$table} WHERE id = {$id}"); } } } return false; }