Example #1
0
 /**
  * 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;
 }
Example #2
0
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;
    }
}
Example #3
0
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;
    }
}