/** * Create an Elgg* object from a given entity row. * * Handles loading all tables into the correct class. * * @param \stdClass $row The row of the entry in the entities table. * * @return \ElggEntity|false * @see get_entity_as_row() * @see add_subtype() * @see get_entity() * @access private * * @throws \ClassException|\InstallationException */ function rowToElggStar($row) { if (!$row instanceof \stdClass) { return $row; } if (!isset($row->guid) || !isset($row->subtype)) { return $row; } $new_entity = false; // Create a memcache cache if we can static $newentity_cache; if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new \ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $new_entity = $newentity_cache->load($row->guid); } if ($new_entity) { return $new_entity; } // load class for entity if one is registered $classname = get_subtype_class_from_id($row->subtype); if ($classname != "") { if (class_exists($classname)) { $new_entity = new $classname($row); if (!$new_entity instanceof \ElggEntity) { $msg = $classname . " is not a " . '\\ElggEntity' . "."; throw new \ClassException($msg); } } else { error_log("Class '" . $classname . "' was not found, missing plugin?"); } } if (!$new_entity) { //@todo Make this into a function switch ($row->type) { case 'object': $new_entity = new \ElggObject($row); break; case 'user': $new_entity = new \ElggUser($row); break; case 'group': $new_entity = new \ElggGroup($row); break; case 'site': $new_entity = new \ElggSite($row); break; default: $msg = "Entity type " . $row->type . " is not supported."; throw new \InstallationException($msg); } } // Cache entity if we have a cache available if ($newentity_cache && $new_entity) { $newentity_cache->save($new_entity->guid, $new_entity); } return $new_entity; }
/** * Create a standard object from a given entity row. * * @param stdClass $row The row of the entry in the entities table. * * @return ElggEntity|false * @link http://docs.elgg.org/DataModel/Entities * @see get_entity_as_row() * @see add_subtype() * @see get_entity() * @access private * * @throws ClassException|InstallationException */ function elasticsearch_entity_row_to_std($row) { if (!$row instanceof stdClass) { return $row; } if (!isset($row->guid) || !isset($row->subtype)) { return $row; } $new_entity = false; // Create a memcache cache if we can static $newentity_cache; if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $new_entity = $newentity_cache->load($row->guid); } if ($new_entity) { return $new_entity; } try { // load class for entity if one is registered $classname = get_subtype_class_from_id($row->subtype); if ($classname != "") { if (class_exists($classname)) { $new_entity = new $classname($row); if (!$new_entity instanceof ElggEntity) { $msg = elgg_echo('ClassException:ClassnameNotClass', array($classname, 'ElggEntity')); throw new ClassException($msg); } } } if (!$new_entity) { switch ($row->type) { case 'object': $new_entity = new ElggObject($row); break; case 'user': $new_entity = new ElggUser($row); break; case 'group': $new_entity = new ElggGroup($row); break; case 'site': $new_entity = new ElggSite($row); break; default: $msg = elgg_echo('InstallationException:TypeNotSupported', array($row->type)); throw new InstallationException($msg); } } } catch (IncompleteEntityException $e) { return false; } return $new_entity; }
/** * 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); } }
/** * Returns a singleton * @return self */ public static function getInstance() { if (is_null(self::$_instance)) { $conf = self::getHttpClientConfig(); $client = new \GuzzleHttp\Client($conf); $parser = new \hypeJunction\Parser($client); $cache = $routes_cache = is_memcache_available() ? new Memcache() : new FileCache(); self::$_instance = new self($parser, $cache); } return self::$_instance; }
/** *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; }
/** * Updates setting cache when parent data is set * * @param string $name setting/metadata being updated * @param mixed $value new value * * @return void */ public function __set($name, $value) { if (is_array($value)) { if (empty($value)) { $value = null; } else { $value = json_encode($value); } } 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()); } }
/** * Logs in a specified ElggUser. For standard registration, use in conjunction * with elgg_authenticate. * * @see elgg_authenticate * * @param ElggUser $user A valid Elgg user object * @param boolean $persistent Should this be a persistent login? * * @return true or throws exception * @throws LoginException */ function login(ElggUser $user, $persistent = false) { // User is banned, return false. if ($user->isBanned()) { throw new LoginException(elgg_echo('LoginException:BannedUser')); } $_SESSION['user'] = $user; $_SESSION['guid'] = $user->getGUID(); $_SESSION['id'] = $_SESSION['guid']; $_SESSION['username'] = $user->username; $_SESSION['name'] = $user->name; // if remember me checked, set cookie with token and store token on user if ($persistent) { $code = md5($user->name . $user->username . time() . rand()); $_SESSION['code'] = $code; $user->code = md5($code); setcookie("elggperm", $code, time() + 86400 * 30, "/"); } if (!$user->save() || !elgg_trigger_event('login', 'user', $user)) { unset($_SESSION['username']); unset($_SESSION['name']); unset($_SESSION['code']); unset($_SESSION['guid']); unset($_SESSION['id']); unset($_SESSION['user']); setcookie("elggperm", "", time() - 86400 * 30, "/"); throw new LoginException(elgg_echo('LoginException:Unknown')); } // Users privilege has been elevated, so change the session id (prevents session fixation) session_regenerate_id(); // Update statistics set_last_login($_SESSION['guid']); reset_login_failure_count($user->guid); // Reset any previous failed login attempts // if memcache is enabled, invalidate the user in memcache @see https://github.com/Elgg/Elgg/issues/3143 if (is_memcache_available()) { // this needs to happen with a shutdown function because of the timing with set_last_login() register_shutdown_function("_elgg_invalidate_memcache_for_entity", $_SESSION['guid']); } return true; }
/** * 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; }
$to = get_entity($to); if (!$from instanceof ElggGroup || !$from->canEdit()) { register_error(elgg_echo("subsite_manager:admin:move_group:permission_denied")); forward(REFERER); } if (!$to instanceof ElggGroup || !$to->canEdit()) { register_error(elgg_echo("subsite_manager:admin:move_group:permission_denied")); forward(REFERER); } if ($from == $to) { register_error(elgg_echo("subsite_manager:admin:move_group:from_to_same")); forward(REFERER); } $submit = get_input("submit"); if (!$submit) { forward("/admin/administer_utilities/move_group?preview=true&from={$from->guid}&to={$to->guid}"); } $dbprefix = elgg_get_config("dbprefix"); $from_acl = $from->group_acl; $to_acl = $to->group_acl; $invalidate_entities = get_data("SELECT guid FROM {$dbprefix}entities WHERE container_guid = {$from->guid}"); update_data("UPDATE {$dbprefix}entities SET container_guid = {$to->guid} WHERE container_guid = {$from->guid}"); update_data("UPDATE {$dbprefix}entities SET access_id = {$to_acl} WHERE access_id = {$from_acl}"); update_data("UPDATE {$dbprefix}metadata SET access_id = {$to_acl} WHERE access_id = {$from_acl}"); update_data("UPDATE {$dbprefix}annotations SET access_id = {$to_acl} WHERE access_id = {$from_acl}"); if (is_memcache_available()) { foreach ($invalidate_entities as $entity) { _elgg_invalidate_memcache_for_entity($entity->guid); } } system_message(elgg_echo("subsite_manager:admin:move_group:success"));
/** * 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; }
/** * Return the meta string id for a given tag, or false. * * @param string $string The value to store * @param bool $case_sensitive Do we want to make the query case sensitive? * If not there may be more than one result * * @return int|array|false meta string id, array of ids or false if none found * @deprecated 1.9 Use elgg_get_metastring_id() */ function get_metastring_id($string, $case_sensitive = TRUE) { elgg_deprecated_notice(__FUNCTION__ . ' is deprecated. Use elgg_get_metastring_id()', 1.9); global $CONFIG, $METASTRINGS_CACHE, $METASTRINGS_DEADNAME_CACHE; $string = sanitise_string($string); // caching doesn't work for case insensitive searches if ($case_sensitive) { $result = array_search($string, $METASTRINGS_CACHE, true); if ($result !== false) { return $result; } // See if we have previously looked for this and found nothing if (in_array($string, $METASTRINGS_DEADNAME_CACHE, true)) { return false; } // Experimental memcache $msfc = null; static $metastrings_memcache; if (!$metastrings_memcache && is_memcache_available()) { $metastrings_memcache = new \ElggMemcache('metastrings_memcache'); } if ($metastrings_memcache) { $msfc = $metastrings_memcache->load($string); } if ($msfc) { return $msfc; } } // Case sensitive if ($case_sensitive) { $query = "SELECT * from {$CONFIG->dbprefix}metastrings where string= BINARY '{$string}' limit 1"; } else { $query = "SELECT * from {$CONFIG->dbprefix}metastrings where string = '{$string}'"; } $row = FALSE; $metaStrings = get_data($query); if (is_array($metaStrings)) { if (sizeof($metaStrings) > 1) { $ids = array(); foreach ($metaStrings as $metaString) { $ids[] = $metaString->id; } return $ids; } else { if (isset($metaStrings[0])) { $row = $metaStrings[0]; } } } if ($row) { $METASTRINGS_CACHE[$row->id] = $row->string; // Cache it // Attempt to memcache it if memcache is available if ($metastrings_memcache) { $metastrings_memcache->save($row->string, $row->id); } return $row->id; } else { $METASTRINGS_DEADNAME_CACHE[$string] = $string; } 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; }
function subsite_manager_get_plugin_order() { if (is_memcache_available()) { $memcache = new ElggMemcache('subsite_manager'); } if (isset($memcache)) { if ($plugin_order = $memcache->load('plugin_order')) { return $plugin_order; } } $db_prefix = get_config('dbprefix'); $priority = elgg_namespace_plugin_private_setting('internal', 'priority'); $options = array('type' => 'object', 'subtype' => 'plugin', 'limit' => ELGG_ENTITIES_NO_VALUE, 'selects' => array('plugin_oe.*'), 'joins' => array("JOIN {$db_prefix}private_settings ps on ps.entity_guid = e.guid", "JOIN {$db_prefix}objects_entity plugin_oe on plugin_oe.guid = e.guid"), 'wheres' => array("ps.name = '{$priority}'"), 'order_by' => "CAST(ps.value as unsigned), e.guid", 'site_guids' => array(1)); $plugins = elgg_get_entities_from_relationship($options); $plugin_order = array(); foreach ($plugins as $i => $plugin) { $plugin_order[$plugin->title] = $i; } if (isset($memcache)) { $memcache->save('plugin_order', $plugin_order); } return $plugin_order; }
/** * 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; }
/** * Loads and returns an entity object from a guid. * * @param int $guid The GUID of the entity * * @return ElggEntity The correct Elgg or custom object based upon entity type and subtype * @link http://docs.elgg.org/DataModel/Entities */ function get_entity($guid) { static $newentity_cache; $new_entity = false; if (!is_numeric($guid)) { return FALSE; } if (!$newentity_cache && is_memcache_available()) { $newentity_cache = new ElggMemcache('new_entity_cache'); } if ($newentity_cache) { $new_entity = $newentity_cache->load($guid); } if ($new_entity) { return $new_entity; } return entity_row_to_elggstar(get_entity_as_row($guid)); }
/** * 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); }
function entity_view_counter_is_counted(ElggEntity $entity) { if (php_sapi_name() === 'cli') { return true; } if (!entity_view_counter_is_configured_entity_type($entity->getType(), $entity->getSubtype())) { return true; } if (isset($_SERVER["HTTP_USER_AGENT"]) && preg_match('/bot|crawl|slurp|spider/i', $_SERVER["HTTP_USER_AGENT"])) { return true; } $user = elgg_get_logged_in_user_entity(); if ($user && $user->getGUID() == $entity->getOwnerGUID()) { return true; } if (is_memcache_available()) { $cache = new ElggMemcache('entity_view_counter'); $key = "view_" . session_id() . "_" . $entity->guid; if ($cache->load($key)) { return true; } } if (entity_view_counter_ignore_ip()) { return true; } return false; }
/** * Loads configuration related to Elgg as an application * * This runs on the engine boot and loads from the datalists database table. * * @see _elgg_engine_boot() * * @access private */ function _elgg_load_application_config() { global $CONFIG, $DATALIST_CACHE; $install_root = str_replace("\\", "/", dirname(dirname(dirname(__FILE__)))); $defaults = array('path' => "{$install_root}/", 'view_path' => "{$install_root}/views/", 'plugins_path' => "{$install_root}/mod/", 'language' => 'en', 'viewpath' => "{$install_root}/views/", 'pluginspath' => "{$install_root}/mod/"); foreach ($defaults as $name => $value) { if (empty($CONFIG->{$name})) { $CONFIG->{$name} = $value; } } // set cookie values for session and remember me if (!isset($CONFIG->cookies)) { $CONFIG->cookies = array(); } if (!isset($CONFIG->cookies['session'])) { $CONFIG->cookies['session'] = array(); } $session_defaults = session_get_cookie_params(); $session_defaults['name'] = 'Elgg'; $CONFIG->cookies['session'] = array_merge($session_defaults, $CONFIG->cookies['session']); if (!isset($CONFIG->cookies['remember_me'])) { $CONFIG->cookies['remember_me'] = array(); } $session_defaults['name'] = 'elggperm'; $session_defaults['expire'] = strtotime("+30 days"); $CONFIG->cookies['remember_me'] = array_merge($session_defaults, $CONFIG->cookies['remember_me']); // load entire datalist // This can cause OOM problems when the datalists table is large // @todo make a list of datalists that we want to get in one grab if (!is_memcache_available()) { $result = get_data("SELECT * FROM {$CONFIG->dbprefix}datalists"); if ($result) { foreach ($result as $row) { $DATALIST_CACHE[$row->name] = $row->value; } } } $path = datalist_get('path'); if (!empty($path)) { $CONFIG->path = $path; } // allow sites to set dataroot and simplecache_enabled in settings.php if (isset($CONFIG->dataroot)) { $CONFIG->dataroot = sanitise_filepath($CONFIG->dataroot); $CONFIG->dataroot_in_settings = true; } else { $dataroot = datalist_get('dataroot'); if (!empty($dataroot)) { $CONFIG->dataroot = $dataroot; } $CONFIG->dataroot_in_settings = false; } if (isset($CONFIG->simplecache_enabled)) { $CONFIG->simplecache_enabled_in_settings = true; } else { $simplecache_enabled = datalist_get('simplecache_enabled'); if ($simplecache_enabled !== false) { $CONFIG->simplecache_enabled = $simplecache_enabled; } else { $CONFIG->simplecache_enabled = 1; } $CONFIG->simplecache_enabled_in_settings = false; } $system_cache_enabled = datalist_get('system_cache_enabled'); if ($system_cache_enabled !== false) { $CONFIG->system_cache_enabled = $system_cache_enabled; } else { $CONFIG->system_cache_enabled = 1; } // initialize context here so it is set before the first get_input call $CONFIG->context = array(); // needs to be set before system, init for links in html head $CONFIG->lastcache = (int) datalist_get("simplecache_lastupdate"); $CONFIG->i18n_loaded_from_cache = false; // this must be synced with the enum for the entities table $CONFIG->entity_types = array('group', 'object', 'site', 'user'); }
/** * Loads and returns an entity object from a guid. * * @param int $guid The GUID of the entity * * @return ElggEntity The correct Elgg or custom object based upon entity type and subtype */ function get_entity($guid) { // This should not be a static local var. Notice that cache writing occurs in a completely // different instance outside this function. // @todo We need a single Memcache instance with a shared pool of namespace wrappers. This function would pull an instance from the pool. static $shared_cache; // We could also use: if (!(int) $guid) { return false }, // but that evaluates to a false positive for $guid = true. // This is a bit slower, but more thorough. if (!is_numeric($guid) || $guid === 0 || $guid === '0') { return false; } // Check local cache first $new_entity = _elgg_retrieve_cached_entity($guid); if ($new_entity) { return $new_entity; } // Check shared memory cache, if available if (null === $shared_cache) { if (is_memcache_available()) { $shared_cache = new ElggMemcache('new_entity_cache'); } else { $shared_cache = false; } } // until ACLs in memcache, DB query is required to determine access $entity_row = get_entity_as_row($guid); if (!$entity_row) { return false; } if ($shared_cache) { $cached_entity = $shared_cache->load($guid); // @todo store ACLs in memcache https://github.com/elgg/elgg/issues/3018#issuecomment-13662617 if ($cached_entity) { // @todo use ACL and cached entity access_id to determine if user can see it return $cached_entity; } } // don't let incomplete entities cause fatal exceptions try { $new_entity = entity_row_to_elggstar($entity_row); } catch (IncompleteEntityException $e) { return false; } if ($new_entity) { _elgg_cache_entity($new_entity); } return $new_entity; }
/** * 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; }
/** * Logs in a specified \ElggUser. For standard registration, use in conjunction * with elgg_authenticate. * * @see elgg_authenticate * * @param \ElggUser $user A valid Elgg user object * @param boolean $persistent Should this be a persistent login? * * @return true or throws exception * @throws LoginException */ function login(\ElggUser $user, $persistent = false) { if ($user->isBanned()) { throw new \LoginException(elgg_echo('LoginException:BannedUser')); } $session = _elgg_services()->session; // give plugins a chance to reject the login of this user (no user in session!) if (!elgg_trigger_before_event('login', 'user', $user)) { throw new \LoginException(elgg_echo('LoginException:Unknown')); } // #5933: set logged in user early so code in login event will be able to // use elgg_get_logged_in_user_entity(). $session->setLoggedInUser($user); // deprecate event $message = "The 'login' event was deprecated. Register for 'login:before' or 'login:after'"; $version = "1.9"; if (!elgg_trigger_deprecated_event('login', 'user', $user, $message, $version)) { $session->removeLoggedInUser(); throw new \LoginException(elgg_echo('LoginException:Unknown')); } // if remember me checked, set cookie with token and store hash(token) for user if ($persistent) { _elgg_services()->persistentLogin->makeLoginPersistent($user); } // User's privilege has been elevated, so change the session id (prevents session fixation) $session->migrate(); set_last_login($user->guid); reset_login_failure_count($user->guid); elgg_trigger_after_event('login', 'user', $user); // if memcache is enabled, invalidate the user in memcache @see https://github.com/Elgg/Elgg/issues/3143 if (is_memcache_available()) { $guid = $user->getGUID(); // this needs to happen with a shutdown function because of the timing with set_last_login() register_shutdown_function("_elgg_invalidate_memcache_for_entity", $guid); } return true; }
/** * Loads configuration related to Elgg as an application * * This runs on the engine boot and loads from the datalists database table. * * @see _elgg_engine_boot() * * @access private */ function _elgg_load_application_config() { global $CONFIG; $install_root = str_replace("\\", "/", dirname(dirname(dirname(__FILE__)))); $defaults = array('path' => "{$install_root}/", 'plugins_path' => "{$install_root}/mod/", 'language' => 'en', 'pluginspath' => "{$install_root}/mod/"); foreach ($defaults as $name => $value) { if (empty($CONFIG->{$name})) { $CONFIG->{$name} = $value; } } $GLOBALS['_ELGG']->view_path = "{$install_root}/views/"; // set cookie values for session and remember me _elgg_configure_cookies($CONFIG); if (!is_memcache_available()) { _elgg_services()->datalist->loadAll(); } // allow sites to set dataroot and simplecache_enabled in settings.php if (isset($CONFIG->dataroot)) { $CONFIG->dataroot = sanitise_filepath($CONFIG->dataroot); $GLOBALS['_ELGG']->dataroot_in_settings = true; } else { $dataroot = datalist_get('dataroot'); if (!empty($dataroot)) { $CONFIG->dataroot = $dataroot; } $GLOBALS['_ELGG']->dataroot_in_settings = false; } if (isset($CONFIG->simplecache_enabled)) { $GLOBALS['_ELGG']->simplecache_enabled_in_settings = true; } else { $simplecache_enabled = datalist_get('simplecache_enabled'); if ($simplecache_enabled !== false) { $CONFIG->simplecache_enabled = $simplecache_enabled; } else { $CONFIG->simplecache_enabled = 1; } $GLOBALS['_ELGG']->simplecache_enabled_in_settings = false; } $system_cache_enabled = datalist_get('system_cache_enabled'); if ($system_cache_enabled !== false) { $CONFIG->system_cache_enabled = $system_cache_enabled; } else { $CONFIG->system_cache_enabled = 1; } // needs to be set before system, init for links in html head $CONFIG->lastcache = (int) datalist_get("simplecache_lastupdate"); $GLOBALS['_ELGG']->i18n_loaded_from_cache = false; // this must be synced with the enum for the entities table $CONFIG->entity_types = array('group', 'object', 'site', 'user'); }
/** * 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; }
/** * 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; }
/** * Loads configuration related to Elgg as an application * * This runs on the engine boot and loads from the datalists database table. * * @see _elgg_engine_boot() * * @access private */ function _elgg_load_application_config() { _elgg_services()->timer->begin([__FUNCTION__]); global $CONFIG; $install_root = Directory\Local::root(); $defaults = array('path' => $install_root->getPath("/"), 'plugins_path' => $install_root->getPath("mod") . "/", 'language' => 'en', 'pluginspath' => $install_root->getPath("mod") . "/"); foreach ($defaults as $name => $value) { if (empty($CONFIG->{$name})) { $CONFIG->{$name} = $value; } } $GLOBALS['_ELGG']->view_path = \Elgg\Application::elggDir()->getPath("/views/"); // set cookie values for session and remember me _elgg_configure_cookies($CONFIG); if (!is_memcache_available()) { _elgg_services()->datalist->loadAll(); } // make sure dataroot gets set \Elgg\Application::getDataPath(); if (!$GLOBALS['_ELGG']->simplecache_enabled_in_settings) { $simplecache_enabled = datalist_get('simplecache_enabled'); $CONFIG->simplecache_enabled = $simplecache_enabled === false ? 1 : $simplecache_enabled; } $system_cache_enabled = datalist_get('system_cache_enabled'); $CONFIG->system_cache_enabled = $system_cache_enabled === false ? 1 : $system_cache_enabled; // needs to be set before system, init for links in html head $CONFIG->lastcache = (int) datalist_get("simplecache_lastupdate"); $GLOBALS['_ELGG']->i18n_loaded_from_cache = false; // this must be synced with the enum for the entities table $CONFIG->entity_types = array('group', 'object', 'site', 'user'); _elgg_services()->timer->end([__FUNCTION__]); }
/** * 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; } }
/** * 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; }
/** * 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; }
/** * 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; }
* * @package ElggPages */ $guid = get_input('guid'); $page = get_entity($guid); if (elgg_instanceof($page, 'object', 'page') || elgg_instanceof($page, 'object', 'page_top')) { // only allow owners and admin to delete if (elgg_is_admin_logged_in() || elgg_get_logged_in_user_guid() == $page->getOwnerGuid()) { $container = get_entity($page->container_guid); // 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); } } } }