/** * Returns an array of entities with optional filtering. * * Entities are the basic unit of storage in Elgg. This function * provides the simplest way to get an array of entities. There * are many options available that can be passed to filter * what sorts of entities are returned. * * @tip To output formatted strings of entities, use {@link elgg_list_entities()} and * its cousins. * * @tip Plural arguments can be written as singular if only specifying a * single element. ('type' => 'object' vs 'types' => array('object')). * * @param array $options Array in format: * * types => null|STR entity type (type IN ('type1', 'type2') * Joined with subtypes by AND. See below) * * subtypes => null|STR entity subtype (SQL: subtype IN ('subtype1', 'subtype2)) * Use ELGG_ENTITIES_NO_VALUE for no subtype. * * type_subtype_pairs => null|ARR (array('type' => 'subtype')) * (type = '$type' AND subtype = '$subtype') pairs * * guids => null|ARR Array of entity guids * * owner_guids => null|ARR Array of owner guids * * container_guids => null|ARR Array of container_guids * * site_guids => null (current_site)|ARR Array of site_guid * * order_by => null (time_created desc)|STR SQL order by clause * * reverse_order_by => BOOL Reverse the default order by clause * * limit => null (10)|INT SQL limit clause (0 means no limit) * * offset => null (0)|INT SQL offset clause * * created_time_lower => null|INT Created time lower boundary in epoch time * * created_time_upper => null|INT Created time upper boundary in epoch time * * modified_time_lower => null|INT Modified time lower boundary in epoch time * * modified_time_upper => null|INT Modified time upper boundary in epoch time * * count => true|false return a count instead of entities * * wheres => array() Additional where clauses to AND together * * joins => array() Additional joins * * preload_owners => bool (false) If set to true, this function will preload * all the owners of the returned entities resulting in better * performance if those owners need to be displayed * * preload_containers => bool (false) If set to true, this function will preload * all the containers of the returned entities resulting in better * performance if those containers need to be displayed * * * callback => string A callback function to pass each row through * * distinct => bool (true) If set to false, Elgg will drop the DISTINCT clause from * the MySQL query, which will improve performance in some situations. * Avoid setting this option without a full understanding of the underlying * SQL query Elgg creates. * * @return mixed If count, int. If not count, array. false on errors. * @see elgg_get_entities_from_metadata() * @see elgg_get_entities_from_relationship() * @see elgg_get_entities_from_access_id() * @see elgg_get_entities_from_annotations() * @see elgg_list_entities() */ function getEntities(array $options = array()) { $defaults = array('types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'guids' => ELGG_ENTITIES_ANY_VALUE, 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'container_guids' => ELGG_ENTITIES_ANY_VALUE, 'site_guids' => $this->CONFIG->site_guid, 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'reverse_order_by' => false, 'order_by' => 'e.time_created desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'limit' => _elgg_services()->config->get('default_limit'), 'offset' => 0, 'count' => false, 'selects' => array(), 'wheres' => array(), 'joins' => array(), 'preload_owners' => false, 'preload_containers' => false, 'callback' => 'entity_row_to_elggstar', 'distinct' => true, '__ElggBatch' => null); $options = array_merge($defaults, $options); // can't use helper function with type_subtype_pair because // it's already an array...just need to merge it if (isset($options['type_subtype_pair'])) { if (isset($options['type_subtype_pairs'])) { $options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], $options['type_subtype_pair']); } else { $options['type_subtype_pairs'] = $options['type_subtype_pair']; } } $singulars = array('type', 'subtype', 'guid', 'owner_guid', 'container_guid', 'site_guid'); $options = _elgg_normalize_plural_options_array($options, $singulars); $options = $this->autoJoinTables($options); // evaluate where clauses if (!is_array($options['wheres'])) { $options['wheres'] = array($options['wheres']); } $wheres = $options['wheres']; $wheres[] = _elgg_get_entity_type_subtype_where_sql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']); $wheres[] = _elgg_get_guid_based_where_sql('e.guid', $options['guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']); $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']); // see if any functions failed // remove empty strings on successful functions foreach ($wheres as $i => $where) { if ($where === false) { return false; } elseif (empty($where)) { unset($wheres[$i]); } } // remove identical where clauses $wheres = array_unique($wheres); // evaluate join clauses if (!is_array($options['joins'])) { $options['joins'] = array($options['joins']); } // remove identical join clauses $joins = array_unique($options['joins']); foreach ($joins as $i => $join) { if ($join === false) { return false; } elseif (empty($join)) { unset($joins[$i]); } } // evalutate selects if ($options['selects']) { $selects = ''; foreach ($options['selects'] as $select) { $selects .= ", {$select}"; } } else { $selects = ''; } if (!$options['count']) { $distinct = $options['distinct'] ? "DISTINCT" : ""; $query = "SELECT {$distinct} e.*{$selects} FROM {$this->CONFIG->dbprefix}entities e "; } else { // note: when DISTINCT unneeded, it's slightly faster to compute COUNT(*) than GUIDs $count_expr = $options['distinct'] ? "DISTINCT e.guid" : "*"; $query = "SELECT COUNT({$count_expr}) as total FROM {$this->CONFIG->dbprefix}entities e "; } // add joins foreach ($joins as $j) { $query .= " {$j} "; } // add wheres $query .= ' WHERE '; foreach ($wheres as $w) { $query .= " {$w} AND "; } // Add access controls $query .= _elgg_get_access_where_sql(); // reverse order by if ($options['reverse_order_by']) { $options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']); } if ($options['count']) { $total = _elgg_services()->db->getDataRow($query); return (int) $total->total; } if ($options['group_by']) { $query .= " GROUP BY {$options['group_by']}"; } if ($options['order_by']) { $query .= " ORDER BY {$options['order_by']}"; } if ($options['limit']) { $limit = sanitise_int($options['limit'], false); $offset = sanitise_int($options['offset'], false); $query .= " LIMIT {$offset}, {$limit}"; } if ($options['callback'] === 'entity_row_to_elggstar') { $results = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']); } else { $results = _elgg_services()->db->getData($query, $options['callback']); } if (!$results) { // no results, no preloading return $results; } // populate entity and metadata caches, and prepare $entities for preloader $guids = array(); foreach ($results as $item) { // A custom callback could result in items that aren't \ElggEntity's, so check for them if ($item instanceof \ElggEntity) { _elgg_cache_entity($item); // plugins usually have only settings if (!$item instanceof \ElggPlugin) { $guids[] = $item->guid; } } } // @todo Without this, recursive delete fails. See #4568 reset($results); if ($guids) { // there were entities in the result set, preload metadata for them _elgg_services()->metadataCache->populateFromEntities($guids); } if (count($results) > 1) { $props_to_preload = []; if ($options['preload_owners']) { $props_to_preload[] = 'owner_guid'; } if ($options['preload_containers']) { $props_to_preload[] = 'container_guid'; } if ($props_to_preload) { // note, ElggEntityPreloaderIntegrationTest assumes it can swap out // the preloader after boot. If you inject this component at construction // time that unit test will break. :/ _elgg_services()->entityPreloader->preload($results, $props_to_preload); } } return $results; }
function elgg_solr_get_entity_guids(array $options = array()) { global $CONFIG; $defaults = array('types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'guids' => ELGG_ENTITIES_ANY_VALUE, 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'container_guids' => ELGG_ENTITIES_ANY_VALUE, 'site_guids' => $CONFIG->site_guid, 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'reverse_order_by' => false, 'order_by' => 'e.time_created desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 10, 'offset' => 0, 'count' => false, 'selects' => array(), 'wheres' => array(), 'joins' => array(), 'callback' => false, '__ElggBatch' => null); $options = array_merge($defaults, $options); // can't use helper function with type_subtype_pair because // it's already an array...just need to merge it if (isset($options['type_subtype_pair'])) { if (isset($options['type_subtype_pairs'])) { $options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], $options['type_subtype_pair']); } else { $options['type_subtype_pairs'] = $options['type_subtype_pair']; } } $singulars = array('type', 'subtype', 'guid', 'owner_guid', 'container_guid', 'site_guid'); $options = _elgg_normalize_plural_options_array($options, $singulars); // evaluate where clauses if (!is_array($options['wheres'])) { $options['wheres'] = array($options['wheres']); } $wheres = $options['wheres']; $wheres[] = _elgg_get_entity_type_subtype_where_sql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']); $wheres[] = _elgg_get_guid_based_where_sql('e.guid', $options['guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']); $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']); // see if any functions failed // remove empty strings on successful functions foreach ($wheres as $i => $where) { if ($where === false) { return false; } elseif (empty($where)) { unset($wheres[$i]); } } // remove identical where clauses $wheres = array_unique($wheres); // evaluate join clauses if (!is_array($options['joins'])) { $options['joins'] = array($options['joins']); } // remove identical join clauses $joins = array_unique($options['joins']); foreach ($joins as $i => $join) { if ($join === false) { return false; } elseif (empty($join)) { unset($joins[$i]); } } // evalutate selects if ($options['selects']) { $selects = ''; foreach ($options['selects'] as $select) { $selects .= ", {$select}"; } } else { $selects = ''; } if (!$options['count']) { $distinct = ''; if ($options['require_distinct']) { $distinct = ' DISTINCT'; } $query = "SELECT{$distinct} e.guid{$selects} FROM {$CONFIG->dbprefix}entities e "; } else { $query = "SELECT count(DISTINCT e.guid) as total FROM {$CONFIG->dbprefix}entities e "; } // add joins foreach ($joins as $j) { $query .= " {$j} "; } // add wheres $query .= ' WHERE '; foreach ($wheres as $w) { $query .= " {$w} AND "; } // Add access controls $query .= _elgg_get_access_where_sql(); // reverse order by if ($options['reverse_order_by']) { $options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']); } if (!$options['count']) { if ($options['group_by']) { $query .= " GROUP BY {$options['group_by']}"; } if ($options['order_by']) { $query .= " ORDER BY {$options['order_by']}"; } if ($options['limit']) { $limit = sanitise_int($options['limit'], false); $offset = sanitise_int($options['offset'], false); $query .= " LIMIT {$offset}, {$limit}"; } if ($options['callback'] === 'entity_row_to_elggstar') { $dt = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']); } else { $dt = get_data($query, $options['callback']); } if ($dt) { // populate entity and metadata caches $guids = array(); foreach ($dt as $item) { // A custom callback could result in items that aren't ElggEntity's, so check for them if ($item instanceof ElggEntity) { _elgg_cache_entity($item); // plugins usually have only settings if (!$item instanceof ElggPlugin) { $guids[] = $item->guid; } } } // @todo Without this, recursive delete fails. See #4568 reset($dt); if ($guids) { _elgg_get_metadata_cache()->populateFromEntities($guids); } } return $dt; } else { $total = get_data_row($query); return (int) $total->total; } }
function elgg_solr_get_entity_guids(array $options = array()) { $dbprefix = elgg_get_config('dbprefix'); $defaults = array('types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'guids' => ELGG_ENTITIES_ANY_VALUE, 'owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'container_guids' => ELGG_ENTITIES_ANY_VALUE, 'site_guids' => elgg_get_site_entity()->guid, 'modified_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'modified_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'reverse_order_by' => false, 'order_by' => 'e.time_created desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 10, 'offset' => 0, 'count' => false, 'selects' => array(), 'wheres' => array(), 'joins' => array(), 'callback' => false, '__ElggBatch' => null); $options = array_merge($defaults, $options); // can't use helper function with type_subtype_pair because // it's already an array...just need to merge it if (isset($options['type_subtype_pair'])) { if (isset($options['type_subtype_pairs'])) { $options['type_subtype_pairs'] = array_merge($options['type_subtype_pairs'], $options['type_subtype_pair']); } else { $options['type_subtype_pairs'] = $options['type_subtype_pair']; } } $singulars = array('type', 'subtype', 'guid', 'owner_guid', 'container_guid', 'site_guid'); $options = _elgg_normalize_plural_options_array($options, $singulars); // evaluate where clauses if (!is_array($options['wheres'])) { $options['wheres'] = array($options['wheres']); } $wheres = $options['wheres']; $wheres[] = _elgg_services()->entityTable->getEntityTypeSubtypeWhereSql('e', $options['types'], $options['subtypes'], $options['type_subtype_pairs']); $wheres[] = _elgg_get_guid_based_where_sql('e.guid', $options['guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.owner_guid', $options['owner_guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.container_guid', $options['container_guids']); $wheres[] = _elgg_get_guid_based_where_sql('e.site_guid', $options['site_guids']); $wheres[] = _elgg_get_entity_time_where_sql('e', $options['created_time_upper'], $options['created_time_lower'], $options['modified_time_upper'], $options['modified_time_lower']); // see if any functions failed // remove empty strings on successful functions foreach ($wheres as $i => $where) { if ($where === false) { return false; } elseif (empty($where)) { unset($wheres[$i]); } } // remove identical where clauses $wheres = array_unique($wheres); // evaluate join clauses if (!is_array($options['joins'])) { $options['joins'] = array($options['joins']); } // remove identical join clauses $joins = array_unique($options['joins']); foreach ($joins as $i => $join) { if ($join === false) { return false; } elseif (empty($join)) { unset($joins[$i]); } } // evalutate selects if ($options['selects']) { $selects = ''; foreach ($options['selects'] as $select) { $selects .= ", {$select}"; } } else { $selects = ''; } if (!$options['count']) { $distinct = ''; if ($options['require_distinct']) { $distinct = ' DISTINCT'; } $query = "SELECT{$distinct} e.guid{$selects} FROM {$dbprefix}entities e "; } else { $query = "SELECT count(DISTINCT e.guid) as total FROM {$dbprefix}entities e "; } // add joins foreach ($joins as $j) { $query .= " {$j} "; } // add wheres $query .= ' WHERE '; foreach ($wheres as $w) { $query .= " {$w} AND "; } // Add access controls $query .= _elgg_get_access_where_sql(); // reverse order by if ($options['reverse_order_by']) { $options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']); } if (!$options['count']) { if ($options['group_by']) { $query .= " GROUP BY {$options['group_by']}"; } if ($options['order_by']) { $query .= " ORDER BY {$options['order_by']}"; } if ($options['limit']) { $limit = sanitise_int($options['limit'], false); $offset = sanitise_int($options['offset'], false); $query .= " LIMIT {$offset}, {$limit}"; } if ($options['callback'] === 'entity_row_to_elggstar') { $dt = _elgg_fetch_entities_from_sql($query, $options['__ElggBatch']); } else { $dt = get_data($query, $options['callback']); } return $dt; } else { $total = get_data_row($query); return (int) $total->total; } }