/** * 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)); }
/** * Hook to transform a search result to an Elgg Entity * * @param string $hook the name of the hook * @param string $type the type of the hook * @param Client $returnvalue current return value * @param array $params supplied params * * @return void|Client */ public static function sourceToEntity($hook, $type, $returnvalue, $params) { $hit = elgg_extract('hit', $params); $index = elgg_extract('_index', $hit); $elgg_index = elasticsearch_get_setting('index'); if ($index !== $elgg_index) { return; } $source = elgg_extract('_source', $hit); $row = new \stdClass(); foreach ($source as $key => $value) { switch ($key) { case 'subtype': // elastic stores the textual version of the subtype, entity_row_to_elggstar needs the int $row->{$key} = get_subtype_id($source['type'], $value); break; case 'last_action': case 'time_created': case 'time_updated': // convert the timestamps to unix timestamps $value = strtotime($value); default: $row->{$key} = $value; break; } } // enabled attribute is not stored in elasticsearch by default $row->enabled = 'yes'; // specials types if ($row->type == 'user') { // makes sure all attributes are loaded to prevent a db call $external_attributes = \ElggUser::getExternalAttributes(); foreach ($external_attributes as $key => $value) { if (isset($row->{$key})) { continue; } $row->{$key} = $value; } } try { $result = entity_row_to_elggstar($row); } catch (\Exception $e) { elgg_log($e->getMessage(), 'NOTICE'); return; } return $result; }
/** * Return entities from an SQL query generated by elgg_get_entities. * * @param string $sql * @param \ElggBatch $batch * @return \ElggEntity[] * * @access private * @throws \LogicException */ function fetchFromSql($sql, \ElggBatch $batch = null) { static $plugin_subtype; if (null === $plugin_subtype) { $plugin_subtype = get_subtype_id('object', 'plugin'); } // Keys are types, values are columns that, if present, suggest that the secondary // table is already JOINed. Note it's OK if guess incorrectly because entity load() // will fetch any missing attributes. $types_to_optimize = array('object' => 'title', 'user' => 'password', 'group' => 'name', 'site' => 'url'); $rows = _elgg_services()->db->getData($sql); // guids to look up in each type $lookup_types = array(); // maps GUIDs to the $rows key $guid_to_key = array(); if (isset($rows[0]->type, $rows[0]->subtype) && $rows[0]->type === 'object' && $rows[0]->subtype == $plugin_subtype) { // Likely the entire resultset is plugins, which have already been optimized // to JOIN the secondary table. In this case we allow retrieving from cache, // but abandon the extra queries. $types_to_optimize = array(); } // First pass: use cache where possible, gather GUIDs that we're optimizing foreach ($rows as $i => $row) { if (empty($row->guid) || empty($row->type)) { throw new \LogicException('Entity row missing guid or type'); } $entity = _elgg_retrieve_cached_entity($row->guid); if ($entity) { $entity->refresh($row); $rows[$i] = $entity; continue; } if (isset($types_to_optimize[$row->type])) { // check if row already looks JOINed. if (isset($row->{$types_to_optimize[$row->type]})) { // Row probably already contains JOINed secondary table. Don't make another query just // to pull data that's already there continue; } $lookup_types[$row->type][] = $row->guid; $guid_to_key[$row->guid] = $i; } } // Do secondary queries and merge rows if ($lookup_types) { $dbprefix = _elgg_services()->config->get('dbprefix'); foreach ($lookup_types as $type => $guids) { $set = "(" . implode(',', $guids) . ")"; $sql = "SELECT * FROM {$dbprefix}{$type}s_entity WHERE guid IN {$set}"; $secondary_rows = _elgg_services()->db->getData($sql); if ($secondary_rows) { foreach ($secondary_rows as $secondary_row) { $key = $guid_to_key[$secondary_row->guid]; // cast to arrays to merge then cast back $rows[$key] = (object) array_merge((array) $rows[$key], (array) $secondary_row); } } } } // Second pass to finish conversion foreach ($rows as $i => $row) { if ($row instanceof \ElggEntity) { continue; } else { try { $rows[$i] = entity_row_to_elggstar($row); } catch (IncompleteEntityException $e) { // don't let incomplete entities throw fatal errors unset($rows[$i]); // report incompletes to the batch process that spawned this query if ($batch) { $batch->reportIncompleteEntity($row); } } } } return $rows; }
function pleio_api_get_messages($sent = 0, $search = "", $offset = 0) { $total = 0; $list = array(); $user = elgg_get_logged_in_user_entity(); $user_id = $user !== false ? $user->guid : 0; $searchSql = ""; $searchJoin = ""; $subtype_id = get_subtype_id('object', 'messages'); if (!$user) { return new ErrorResult($fail); } try { if ($search) { $search = sanitise_string($search); $searchSql = " AND (description LIKE '%%{$search}%%' OR title LIKE '%%{$search}%%' "; $sql = "select guid from " . get_config("dbprefix") . "users_entity where name like '%{$search}%' "; $users = get_data($sql); if (sizeof($users)) { $users = array_map(create_function('$user', 'return $user->guid;'), $users); $users = implode(",", $users); $searchSql .= " OR (msn2.string = '" . ($sent ? "toId" : "fromId") . "' AND msv2.string in ({$users})) "; $searchJoin = " INNER JOIN " . get_config("dbprefix") . "metadata n_table2 on e.guid = n_table2.entity_guid \r\n\t\t\t\t\t\t\t\t\t\tINNER JOIN " . get_config("dbprefix") . "metastrings msn2 on n_table2.name_id = msn2.id \r\n\t\t\t\t\t\t\t\t\t\tINNER JOIN " . get_config("dbprefix") . "metastrings msv2 on n_table2.value_id = msv2.id "; } $searchSql .= ")"; } $offset = intval($offset); $sent_sql = $sent ? "fromId" : "toId"; $sql = "SELECT %s \r\n\t\t\tFROM " . get_config("dbprefix") . "entities e\r\n\t\t\tINNER JOIN " . get_config("dbprefix") . "objects_entity o on e.guid = o.guid \r\n\t\t\tINNER JOIN " . get_config("dbprefix") . "metadata n_table on e.guid = n_table.entity_guid \r\n\t\t\tINNER JOIN " . get_config("dbprefix") . "metastrings msn on n_table.name_id = msn.id \r\n\t\t\tINNER JOIN " . get_config("dbprefix") . "metastrings msv on n_table.value_id = msv.id\r\n\t\t\t{$searchJoin}\t\r\n\t\t\tWHERE e.owner_guid = %d\r\n\t\t\t{$searchSql} \r\n\t\t\tAND e.type = 'object' AND e.subtype = {$subtype_id}\r\n\t\t\tAND msn.string ='{$sent_sql}' AND msv.string = %d \r\n\t\t\tAND e.enabled = 'yes' "; $total = get_data_row(sprintf($sql, "COUNT(e.guid) AS cnt", $user_id, $user_id)); $total = $total->cnt; $data = get_data(sprintf($sql, "DISTINCT e.*", $user_id, $user_id) . sprintf("ORDER BY e.time_created DESC LIMIT %d, 20", $offset)); foreach ($data as $row) { $message = entity_row_to_elggstar($row); $export = pleio_api_export($message, array("time_created", "guid", "owner_guid", "container_guid", "site_guid", "title", "description")); $export = pleio_api_get_metadata($message->guid, $export); unset($export["msg"]); // filter links $export["description"] = strip_tags(trim(preg_replace("/\\w+:\\/\\/[\\w\\d\\.\\-_\\?=&;:#\\/]+/ism", "", $export["description"]), ": ")); $u = false; if ($export["fromId"] == $user_id) { $u = get_entity($export["toId"]); } elseif ($export["toId"] == $user_id) { $u = get_entity($export["fromId"]); } $export["name"] = $u->name; if ($u instanceof ElggUser) { $u = pleio_api_format_user($u); $export["avatar"] = $u["avatar"]; } $sender_and_reciever = false; if ($export["fromId"] == $export["toId"] && $export["fromId"] == $user_id) { foreach ($list as $e) { if ($e["guid"] == $export["guid"] + 1 || $e["guid"] == $export["guid"] - 1) { $sender_and_reciever = true; $total--; } } } if (!$sender_and_reciever) { $list[] = $export; } } } catch (Exception $ex) { return new ErrorResult(elgg_echo("error:default")); } return array("total" => $total, "list" => $list, "offset" => $offset); }
/** * 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; // 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; } 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)); }
/** * Set proximity select as volatile data on a constructed entity * @todo Make this a class method in 1.9 (1.8 doesn't use call_user_func()) * @param stdClass $row * @return ElggEntity */ function mappable_entity_row_to_elggstar($row) { $entity = entity_row_to_elggstar($row); if (elgg_instanceof($entity)) { $entity->setVolatileData('select:proximity', (double) $row->proximity); } return $entity; }