Exemplo n.º 1
0
 /**
  * Returns entities based upon private settings
  *
  * Also accepts all options available to elgg_get_entities(). Supports
  * the singular option shortcut.
  *
  * @param array $options Array in format:
  *
  *  private_setting_names => null|ARR private setting names
  *
  *  private_setting_values => null|ARR metadata values
  *
  *  private_setting_name_value_pairs => null|ARR (
  *                                       name => 'name',
  *                                       value => 'value',
  *                                       'operand' => '=',
  *                                      )
  *                               Currently if multiple values are sent via
  *                               an array (value => array('value1', 'value2')
  *                               the pair's operand will be forced to "IN".
  *
  *  private_setting_name_value_pairs_operator => null|STR The operator to
  *                                 use for combining
  *                                 (name = value) OPERATOR (name = value);
  *                                 default AND
  *
  *  private_setting_name_prefix => STR A prefix to apply to all private
  *                                 settings. Used to namespace plugin user
  *                                 settings or by plugins to namespace their
  *                                 own settings.
  *
  * @return mixed int If count, int. If not count, array. false on errors.
  */
 public function getEntities(array $options = array())
 {
     $defaults = array('private_setting_names' => ELGG_ENTITIES_ANY_VALUE, 'private_setting_values' => ELGG_ENTITIES_ANY_VALUE, 'private_setting_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'private_setting_name_value_pairs_operator' => 'AND', 'private_setting_name_prefix' => '');
     $options = array_merge($defaults, $options);
     $singulars = array('private_setting_name', 'private_setting_value', 'private_setting_name_value_pair');
     $options = _elgg_normalize_plural_options_array($options, $singulars);
     $clauses = $this->getWhereSql('e', $options['private_setting_names'], $options['private_setting_values'], $options['private_setting_name_value_pairs'], $options['private_setting_name_value_pairs_operator'], $options['private_setting_name_prefix']);
     if ($clauses) {
         // merge wheres to pass to get_entities()
         if (isset($options['wheres']) && !is_array($options['wheres'])) {
             $options['wheres'] = array($options['wheres']);
         } elseif (!isset($options['wheres'])) {
             $options['wheres'] = array();
         }
         $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']);
         // merge joins to pass to get_entities()
         if (isset($options['joins']) && !is_array($options['joins'])) {
             $options['joins'] = array($options['joins']);
         } elseif (!isset($options['joins'])) {
             $options['joins'] = array();
         }
         $options['joins'] = array_merge($options['joins'], $clauses['joins']);
     }
     return $this->entities->getEntities($options);
 }
Exemplo n.º 2
0
/**
 * Delete river items
 *
 * @warning Does not fire permission hooks or delete, river events.
 *
 * @param array $options Parameters:
 *   ids                  => INT|ARR River item id(s)
 *   subject_guids        => INT|ARR Subject guid(s)
 *   object_guids         => INT|ARR Object guid(s)
 *   target_guids         => INT|ARR Target guid(s)
 *   annotation_ids       => INT|ARR The identifier of the annotation(s)
 *   action_types         => STR|ARR The river action type(s) identifier
 *   views                => STR|ARR River view(s)
 *
 *   types                => STR|ARR Entity type string(s)
 *   subtypes             => STR|ARR Entity subtype string(s)
 *   type_subtype_pairs   => ARR     Array of type => subtype pairs where subtype
 *                                   can be an array of subtype strings
 *
 *   posted_time_lower    => INT     The lower bound on the time posted
 *   posted_time_upper    => INT     The upper bound on the time posted
 *
 * @return bool
 * @since 1.8.0
 * @deprecated 2.3 Use elgg_get_river() and call delete() on the returned item(s)
 */
function elgg_delete_river(array $options = array())
{
    global $CONFIG;
    // allow core to use this in 2.x w/o warnings
    if (empty($options['__bypass_notice'])) {
        elgg_deprecated_notice(__FUNCTION__ . ' is deprecated. Use elgg_get_river() and call delete() on the returned item(s)', '2.3');
    }
    $defaults = array('ids' => ELGG_ENTITIES_ANY_VALUE, 'subject_guids' => ELGG_ENTITIES_ANY_VALUE, 'object_guids' => ELGG_ENTITIES_ANY_VALUE, 'target_guids' => ELGG_ENTITIES_ANY_VALUE, 'annotation_ids' => ELGG_ENTITIES_ANY_VALUE, 'views' => ELGG_ENTITIES_ANY_VALUE, 'action_types' => ELGG_ENTITIES_ANY_VALUE, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'wheres' => array(), 'joins' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('id', 'subject_guid', 'object_guid', 'target_guid', 'annotation_id', 'action_type', 'view', 'type', 'subtype');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $wheres = $options['wheres'];
    $wheres[] = _elgg_get_guid_based_where_sql('rv.id', $options['ids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.target_guid', $options['target_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
    $wheres[] = _elgg_river_get_action_where_sql($options['action_types']);
    $wheres[] = _elgg_river_get_view_where_sql($options['views']);
    $wheres[] = _elgg_get_river_type_subtype_where_sql('rv', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    if ($options['posted_time_lower'] && is_int($options['posted_time_lower'])) {
        $wheres[] = "rv.posted >= {$options['posted_time_lower']}";
    }
    if ($options['posted_time_upper'] && is_int($options['posted_time_upper'])) {
        $wheres[] = "rv.posted <= {$options['posted_time_upper']}";
    }
    // 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);
    $query = "DELETE rv.* FROM {$CONFIG->dbprefix}river rv ";
    // remove identical join clauses
    $joins = array_unique($options['joins']);
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    $query .= "1=1";
    return delete_data($query);
}
Exemplo n.º 3
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;
    }
}
Exemplo n.º 4
0
/**
 * Get popular tags and their frequencies
 *
 * Supports similar arguments as elgg_get_entities()
 *
 * @param array $options Array in format:
 *
 * 	threshold => INT minimum tag count
 *
 * 	tag_names => array() metadata tag names - must be registered tags
 *
 * 	limit => INT number of tags to return
 *
 *  types => null|STR entity type (SQL: type = '$type')
 *
 * 	subtypes => null|STR entity subtype (SQL: subtype = '$subtype')
 *
 * 	type_subtype_pairs => null|ARR (array('type' => 'subtype'))
 *  (SQL: type = '$type' AND subtype = '$subtype') pairs
 *
 * 	owner_guids => null|INT entity guid
 *
 * 	container_guids => null|INT container_guid
 *
 * 	site_guids => null (current_site)|INT site_guid
 *
 * 	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
 *
 * 	wheres => array() Additional where clauses to AND together
 *
 * 	joins => array() Additional joins
 *
 * @return 	object[]|false If no tags or error, false
 * 						   otherwise, array of objects with ->tag and ->total values
 * @since 1.7.1
 */
function elgg_get_tags(array $options = array())
{
    global $CONFIG;
    $defaults = array('threshold' => 1, 'tag_names' => array(), 'limit' => 10, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => 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, 'joins' => array(), 'wheres' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('type', 'subtype', 'owner_guid', 'container_guid', 'site_guid', 'tag_name');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $registered_tags = elgg_get_registered_tag_metadata_names();
    if (!is_array($options['tag_names'])) {
        return false;
    }
    // empty array so use all registered tag names
    if (count($options['tag_names']) == 0) {
        $options['tag_names'] = $registered_tags;
    }
    $diff = array_diff($options['tag_names'], $registered_tags);
    if (count($diff) > 0) {
        elgg_deprecated_notice('Tag metadata names must be registered by elgg_register_tag_metadata_name()', 1.7);
        // return false;
    }
    $wheres = $options['wheres'];
    // catch for tags that were spaces
    $wheres[] = "msv.string != ''";
    $sanitised_tags = array();
    foreach ($options['tag_names'] as $tag) {
        $sanitised_tags[] = '"' . sanitise_string($tag) . '"';
    }
    $tags_in = implode(',', $sanitised_tags);
    $wheres[] = "(msn.string IN ({$tags_in}))";
    $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.site_guid', $options['site_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_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);
    $joins = $options['joins'];
    $joins[] = "JOIN {$CONFIG->dbprefix}metadata md on md.entity_guid = e.guid";
    $joins[] = "JOIN {$CONFIG->dbprefix}metastrings msv on msv.id = md.value_id";
    $joins[] = "JOIN {$CONFIG->dbprefix}metastrings msn on md.name_id = msn.id";
    // remove identical join clauses
    $joins = array_unique($joins);
    foreach ($joins as $i => $join) {
        if ($join === false) {
            return false;
        } elseif (empty($join)) {
            unset($joins[$i]);
        }
    }
    $query = "SELECT msv.string as tag, count(msv.id) as total ";
    $query .= "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();
    $threshold = sanitise_int($options['threshold']);
    $query .= " GROUP BY msv.string HAVING total >= {$threshold} ";
    $query .= " ORDER BY total DESC ";
    $limit = sanitise_int($options['limit']);
    $query .= " LIMIT {$limit} ";
    return get_data($query);
}
/**
 * Returns entities based upon metadata.  Also accepts all
 * options available to elgg_get_entities().  Supports
 * the singular option shortcut.
 *
 * @note Using metadata_names and metadata_values results in a
 * "names IN (...) AND values IN (...)" clause.  This is subtly
 * differently than default multiple metadata_name_value_pairs, which use
 * "(name = value) AND (name = value)" clauses.
 *
 * When in doubt, use name_value_pairs.
 *
 * To ask for entities that do not have a metadata value, use a custom
 * where clause like this:
 *
 * 	$options['wheres'][] = "NOT EXISTS (
 *			SELECT 1 FROM {$dbprefix}metadata md
 *			WHERE md.entity_guid = e.guid
 *				AND md.name_id = $name_metastring_id
 *				AND md.value_id = $value_metastring_id)";
 *
 * Note the metadata name and value has been denormalized in the above example.
 *
 * @see elgg_get_entities
 *
 * @param array $options Array in format:
 *
 * 	metadata_names => null|ARR metadata names
 *
 * 	metadata_values => null|ARR metadata values
 *
 * 	metadata_name_value_pairs => null|ARR (
 *                                         name => 'name',
 *                                         value => 'value',
 *                                         'operand' => '=',
 *                                         'case_sensitive' => true
 *                                        )
 *                               Currently if multiple values are sent via
 *                               an array (value => array('value1', 'value2')
 *                               the pair's operand will be forced to "IN".
 *                               If passing "IN" as the operand and a string as the value, 
 *                               the value must be a properly quoted and escaped string.
 *
 * 	metadata_name_value_pairs_operator => null|STR The operator to use for combining
 *                                        (name = value) OPERATOR (name = value); default AND
 *
 * 	metadata_case_sensitive => BOOL Overall Case sensitive
 *
 *  order_by_metadata => null|ARR array(
 *                                      'name' => 'metadata_text1',
 *                                      'direction' => ASC|DESC,
 *                                      'as' => text|integer
 *                                     )
 *                                Also supports array('name' => 'metadata_text1')
 *
 *  metadata_owner_guids => null|ARR guids for metadata owners
 *
 * @return ElggEntity[]|mixed If count, int. If not count, array. false on errors.
 * @since 1.7.0
 */
function elgg_get_entities_from_metadata(array $options = array())
{
    $defaults = array('metadata_names' => ELGG_ENTITIES_ANY_VALUE, 'metadata_values' => ELGG_ENTITIES_ANY_VALUE, 'metadata_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'metadata_name_value_pairs_operator' => 'AND', 'metadata_case_sensitive' => true, 'order_by_metadata' => array(), 'metadata_owner_guids' => ELGG_ENTITIES_ANY_VALUE);
    $options = array_merge($defaults, $options);
    $singulars = array('metadata_name', 'metadata_value', 'metadata_name_value_pair', 'metadata_owner_guid');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    if (!($options = _elgg_entities_get_metastrings_options('metadata', $options))) {
        return false;
    }
    return elgg_get_entities($options);
}
Exemplo n.º 6
0
/**
 * Returns entities based upon annotations.  Also accepts all options available
 * to elgg_get_entities() and elgg_get_entities_from_metadata().
 *
 * Entity creation time is selected as maxtime. To sort based upon
 * this, pass 'order_by' => 'maxtime asc' || 'maxtime desc'
 *
 * @see elgg_get_entities
 * @see elgg_get_entities_from_metadata
 *
 * @param array $options Array in format:
 *
 * 	annotation_names => null|ARR annotations names
 *
 * 	annotation_values => null|ARR annotations values
 *
 * 	annotation_name_value_pairs => null|ARR (name = 'name', value => 'value',
 * 	'operator' => '=', 'case_sensitive' => true) entries.
 * 	Currently if multiple values are sent via an array (value => array('value1', 'value2')
 * 	the pair's operator will be forced to "IN".
 *
 * 	annotation_name_value_pairs_operator => null|STR The operator to use for combining
 *  (name = value) OPERATOR (name = value); default AND
 *
 * 	annotation_case_sensitive => BOOL Overall Case sensitive
 *
 *  order_by_annotation => null|ARR (array('name' => 'annotation_text1', 'direction' => ASC|DESC,
 *  'as' => text|integer),
 *
 *  Also supports array('name' => 'annotation_text1')
 *
 *  annotation_owner_guids => null|ARR guids for annotaiton owners
 *
 * @return mixed If count, int. If not count, array. false on errors.
 * @since 1.7.0
 */
function elgg_get_entities_from_annotations(array $options = array())
{
    $defaults = array('annotation_names' => ELGG_ENTITIES_ANY_VALUE, 'annotation_values' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs_operator' => 'AND', 'annotation_case_sensitive' => true, 'order_by_annotation' => array(), 'annotation_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'annotation_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'annotation_owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'order_by' => 'maxtime DESC', 'group_by' => 'a.entity_guid');
    $options = array_merge($defaults, $options);
    $singulars = array('annotation_name', 'annotation_value', 'annotation_name_value_pair', 'annotation_owner_guid');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $options = _elgg_entities_get_metastrings_options('annotation', $options);
    if (!$options) {
        return false;
    }
    // special sorting for annotations
    //@todo overrides other sorting
    $options['selects'][] = "MAX(n_table.time_created) AS maxtime";
    $options['group_by'] = 'n_table.entity_guid';
    $time_wheres = _elgg_get_entity_time_where_sql('a', $options['annotation_created_time_upper'], $options['annotation_created_time_lower']);
    if ($time_wheres) {
        $options['wheres'] = array_merge($options['wheres'], $time_wheres);
    }
    return elgg_get_entities_from_metadata($options);
}
Exemplo n.º 7
0
/**
 * Get river items
 *
 * @note If using types and subtypes in a query, they are joined with an AND.
 *
 * @param array $options Parameters:
 *   ids                  => INT|ARR River item id(s)
 *   subject_guids        => INT|ARR Subject guid(s)
 *   object_guids         => INT|ARR Object guid(s)
 *   target_guids         => INT|ARR Target guid(s)
 *   annotation_ids       => INT|ARR The identifier of the annotation(s)
 *   action_types         => STR|ARR The river action type(s) identifier
 *   posted_time_lower    => INT     The lower bound on the time posted
 *   posted_time_upper    => INT     The upper bound on the time posted
 *
 *   types                => STR|ARR Entity type string(s)
 *   subtypes             => STR|ARR Entity subtype string(s)
 *   type_subtype_pairs   => ARR     Array of type => subtype pairs where subtype
 *                                   can be an array of subtype strings
 *
 *   relationship         => STR     Relationship identifier
 *   relationship_guid    => INT|ARR Entity guid(s)
 *   inverse_relationship => BOOL    Subject or object of the relationship (false)
 *
 * 	 limit                => INT     Number to show per page (20)
 *   offset               => INT     Offset in list (0)
 *   count                => BOOL    Count the river items? (false)
 *   order_by             => STR     Order by clause (rv.posted desc)
 *   group_by             => STR     Group by clause
 *
 *   distinct             => BOOL    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. (true)
 *
 * @return array|int
 * @since 1.8.0
 */
function elgg_get_river(array $options = array())
{
    global $CONFIG;
    $defaults = array('ids' => ELGG_ENTITIES_ANY_VALUE, 'subject_guids' => ELGG_ENTITIES_ANY_VALUE, 'object_guids' => ELGG_ENTITIES_ANY_VALUE, 'target_guids' => ELGG_ENTITIES_ANY_VALUE, 'annotation_ids' => ELGG_ENTITIES_ANY_VALUE, 'action_types' => ELGG_ENTITIES_ANY_VALUE, 'relationship' => null, 'relationship_guid' => null, 'inverse_relationship' => false, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 20, 'offset' => 0, 'count' => false, 'distinct' => true, 'order_by' => 'rv.posted desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'wheres' => array(), 'joins' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('id', 'subject_guid', 'object_guid', 'target_guid', 'annotation_id', 'action_type', 'type', 'subtype');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $wheres = $options['wheres'];
    $wheres[] = _elgg_get_guid_based_where_sql('rv.id', $options['ids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.target_guid', $options['target_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
    $wheres[] = _elgg_river_get_action_where_sql($options['action_types']);
    $wheres[] = _elgg_get_river_type_subtype_where_sql('rv', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    if ($options['posted_time_lower'] && is_int($options['posted_time_lower'])) {
        $wheres[] = "rv.posted >= {$options['posted_time_lower']}";
    }
    if ($options['posted_time_upper'] && is_int($options['posted_time_upper'])) {
        $wheres[] = "rv.posted <= {$options['posted_time_upper']}";
    }
    if (!access_get_show_hidden_status()) {
        $wheres[] = "rv.enabled = 'yes'";
    }
    $joins = $options['joins'];
    $dbprefix = elgg_get_config('dbprefix');
    $joins[] = "JOIN {$dbprefix}entities oe ON rv.object_guid = oe.guid";
    // LEFT JOIN is used because all river items do not necessarily have target
    $joins[] = "LEFT JOIN {$dbprefix}entities te ON rv.target_guid = te.guid";
    if ($options['relationship_guid']) {
        $clauses = elgg_get_entity_relationship_where_sql('rv.subject_guid', $options['relationship'], $options['relationship_guid'], $options['inverse_relationship']);
        if ($clauses) {
            $wheres = array_merge($wheres, $clauses['wheres']);
            $joins = array_merge($joins, $clauses['joins']);
        }
    }
    // 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);
    if (!$options['count']) {
        $distinct = $options['distinct'] ? "DISTINCT" : "";
        $query = "SELECT {$distinct} rv.* FROM {$CONFIG->dbprefix}river rv ";
    } else {
        // note: when DISTINCT unneeded, it's slightly faster to compute COUNT(*) than IDs
        $count_expr = $options['distinct'] ? "DISTINCT rv.id" : "*";
        $query = "SELECT COUNT({$count_expr}) as total FROM {$CONFIG->dbprefix}river rv ";
    }
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    // Make sure that user has access to all the entities referenced by each river item
    $object_access_where = _elgg_get_access_where_sql(array('table_alias' => 'oe'));
    $target_access_where = _elgg_get_access_where_sql(array('table_alias' => 'te'));
    // We use LEFT JOIN with entities table but the WHERE clauses are used
    // regardless if a JOIN is successfully made. The "te.guid IS NULL" is
    // needed because of this.
    $query .= "{$object_access_where} AND ({$target_access_where} OR te.guid IS NULL) ";
    if (!$options['count']) {
        $options['group_by'] = sanitise_string($options['group_by']);
        if ($options['group_by']) {
            $query .= " GROUP BY {$options['group_by']}";
        }
        $options['order_by'] = sanitise_string($options['order_by']);
        $query .= " ORDER BY {$options['order_by']}";
        if ($options['limit']) {
            $limit = sanitise_int($options['limit']);
            $offset = sanitise_int($options['offset'], false);
            $query .= " LIMIT {$offset}, {$limit}";
        }
        $river_items = get_data($query, '_elgg_row_to_elgg_river_item');
        _elgg_prefetch_river_entities($river_items);
        return $river_items;
    } else {
        $total = get_data_row($query);
        return (int) $total->total;
    }
}
Exemplo n.º 8
0
 /**
  * Returns entities based upon annotations.  Also accepts all options available
  * to elgg_get_entities() and elgg_get_entities_from_metadata().
  *
  * @see elgg_get_entities
  * @see elgg_get_entities_from_metadata
  *
  * @param array $options Array in format:
  *
  * 	annotation_names => null|ARR annotations names
  *
  * 	annotation_values => null|ARR annotations values
  *
  * 	annotation_name_value_pairs => null|ARR (name = 'name', value => 'value',
  * 	'operator' => '=', 'case_sensitive' => true) entries.
  * 	Currently if multiple values are sent via an array (value => array('value1', 'value2')
  * 	the pair's operator will be forced to "IN".
  *
  * 	annotation_name_value_pairs_operator => null|STR The operator to use for combining
  *  (name = value) OPERATOR (name = value); default AND
  *
  * 	annotation_case_sensitive => BOOL Overall Case sensitive
  *
  *  order_by_annotation => null|ARR (array('name' => 'annotation_text1', 'direction' => ASC|DESC,
  *  'as' => text|integer),
  *
  *  Also supports array('name' => 'annotation_text1')
  *
  *  annotation_owner_guids => null|ARR guids for annotaiton owners
  *
  * @return mixed If count, int. If not count, array. false on errors.
  */
 function getEntities(array $options = array())
 {
     $defaults = array('annotation_names' => ELGG_ENTITIES_ANY_VALUE, 'annotation_values' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs_operator' => 'AND', 'annotation_case_sensitive' => true, 'order_by_annotation' => array(), 'annotation_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'annotation_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'annotation_owner_guids' => ELGG_ENTITIES_ANY_VALUE);
     $options = array_merge($defaults, $options);
     $singulars = array('annotation_name', 'annotation_value', 'annotation_name_value_pair', 'annotation_owner_guid');
     $options = _elgg_normalize_plural_options_array($options, $singulars);
     $options = _elgg_entities_get_metastrings_options('annotation', $options);
     if (!$options) {
         return false;
     }
     // because of performance issues support for ordering by maxtime has been dropped
     // @see https://github.com/Elgg/Elgg/issues/6638
     if (isset($options['order_by']) && preg_match('~\\bmaxtime\\b~i', $options['order_by'])) {
         // check if the user provided maxtime
         $deprecated = true;
         if (isset($options['selects'])) {
             $selects = $options['selects'];
             if (!is_array($selects)) {
                 $selects = array($selects);
             }
             foreach ($selects as $select) {
                 if (preg_match('~\\bmaxtime\\b~i', $options['order_by'])) {
                     $deprecated = false;
                     break;
                 }
             }
         }
         // the user didn't provide maxtime
         if ($deprecated) {
             // special sorting for annotations
             elgg_deprecated_notice(__FUNCTION__ . ": no longer orders by annotations by default. If you order" . " by maxtime, you must provide that column via \$options['selects']. See" . " https://github.com/Elgg/Elgg/issues/6638#issuecomment-41562034", "1.10");
             $options['selects'][] = "MAX(n_table.time_created) AS maxtime";
             $options['group_by'] = 'n_table.entity_guid';
         }
     }
     $time_wheres = _elgg_get_entity_time_where_sql('a', $options['annotation_created_time_upper'], $options['annotation_created_time_lower']);
     if ($time_wheres) {
         $options['wheres'] = array_merge($options['wheres'], $time_wheres);
     }
     return elgg_get_entities_from_metadata($options);
 }
Exemplo n.º 9
0
 /**
  * Gets entities based upon attributes in secondary tables.
  * Also accepts all options available to elgg_get_entities(),
  * elgg_get_entities_from_metadata(), and elgg_get_entities_from_relationship().
  *
  * @warning requires that the entity type be specified and there can only be one
  * type.
  *
  * @see elgg_get_entities
  * @see elgg_get_entities_from_metadata
  * @see elgg_get_entities_from_relationship
  *
  * @param array $options Array in format:
  *
  * 	attribute_name_value_pairs => ARR (
  *                                   'name' => 'name',
  *                                   'value' => 'value',
  *                                   'operand' => '=', (optional)
  *                                   'case_sensitive' => false (optional)
  *                                  )
  * 	                             If multiple values are sent via
  *                               an array ('value' => array('value1', 'value2')
  *                               the pair's operand will be forced to "IN".
  *
  * 	attribute_name_value_pairs_operator => null|STR The operator to use for combining
  *                                        (name = value) OPERATOR (name = value); default is AND
  *
  * @return \ElggEntity[]|mixed If count, int. If not count, array. false on errors.
  * @throws InvalidArgumentException
  * @todo Does not support ordering by attributes or using an attribute pair shortcut like this ('title' => 'foo')
  */
 function getEntitiesFromAttributes(array $options = array())
 {
     $defaults = array('attribute_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'attribute_name_value_pairs_operator' => 'AND');
     $options = array_merge($defaults, $options);
     $singulars = array('type', 'attribute_name_value_pair');
     $options = _elgg_normalize_plural_options_array($options, $singulars);
     $clauses = _elgg_get_entity_attribute_where_sql($options);
     if ($clauses) {
         // merge wheres to pass to elgg_get_entities()
         if (isset($options['wheres']) && !is_array($options['wheres'])) {
             $options['wheres'] = array($options['wheres']);
         } elseif (!isset($options['wheres'])) {
             $options['wheres'] = array();
         }
         $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']);
         // merge joins to pass to elgg_get_entities()
         if (isset($options['joins']) && !is_array($options['joins'])) {
             $options['joins'] = array($options['joins']);
         } elseif (!isset($options['joins'])) {
             $options['joins'] = array();
         }
         $options['joins'] = array_merge($options['joins'], $clauses['joins']);
     }
     return elgg_get_entities_from_relationship($options);
 }
Exemplo n.º 10
0
 /**
  * Returns entities based upon annotations.  Also accepts all options available
  * to elgg_get_entities() and elgg_get_entities_from_metadata().
  *
  * @see elgg_get_entities
  * @see elgg_get_entities_from_metadata
  *
  * @param array $options Array in format:
  *
  * 	annotation_names => null|ARR annotations names
  *
  * 	annotation_values => null|ARR annotations values
  *
  * 	annotation_name_value_pairs => null|ARR (name = 'name', value => 'value',
  * 	'operator' => '=', 'case_sensitive' => true) entries.
  * 	Currently if multiple values are sent via an array (value => array('value1', 'value2')
  * 	the pair's operator will be forced to "IN".
  *
  * 	annotation_name_value_pairs_operator => null|STR The operator to use for combining
  *  (name = value) OPERATOR (name = value); default AND
  *
  * 	annotation_case_sensitive => BOOL Overall Case sensitive
  *
  *  order_by_annotation => null|ARR (array('name' => 'annotation_text1', 'direction' => ASC|DESC,
  *  'as' => text|integer),
  *
  *  Also supports array('name' => 'annotation_text1')
  *
  *  annotation_owner_guids => null|ARR guids for annotaiton owners
  *
  * @return mixed If count, int. If not count, array. false on errors.
  */
 function getEntities(array $options = array())
 {
     $defaults = array('annotation_names' => ELGG_ENTITIES_ANY_VALUE, 'annotation_values' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs' => ELGG_ENTITIES_ANY_VALUE, 'annotation_name_value_pairs_operator' => 'AND', 'annotation_case_sensitive' => true, 'order_by_annotation' => array(), 'annotation_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'annotation_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'annotation_owner_guids' => ELGG_ENTITIES_ANY_VALUE);
     $options = array_merge($defaults, $options);
     $singulars = array('annotation_name', 'annotation_value', 'annotation_name_value_pair', 'annotation_owner_guid');
     $options = _elgg_normalize_plural_options_array($options, $singulars);
     $options = _elgg_entities_get_metastrings_options('annotation', $options);
     if (!$options) {
         return false;
     }
     $time_wheres = _elgg_get_entity_time_where_sql('n_table', $options['annotation_created_time_upper'], $options['annotation_created_time_lower']);
     if ($time_wheres) {
         $options['wheres'][] = $time_wheres;
     }
     return elgg_get_entities_from_metadata($options);
 }
Exemplo n.º 11
0
 /**
  * Returns entities based upon plugin user settings.
  * Takes all the options for {@link elgg_get_entities_from_private_settings()}
  * in addition to the ones below.
  *
  * @param array $options Array in the format:
  *
  * 	plugin_id => STR The plugin id. Required.
  *
  * 	plugin_user_setting_names => null|ARR private setting names
  *
  * 	plugin_user_setting_values => null|ARR metadata values
  *
  * 	plugin_user_setting_name_value_pairs => null|ARR (
  *                                         name => 'name',
  *                                         value => 'value',
  *                                         'operand' => '=',
  *                                        )
  * 	                             Currently if multiple values are sent via
  *                               an array (value => array('value1', 'value2')
  *                               the pair's operand will be forced to "IN".
  *
  * 	plugin_user_setting_name_value_pairs_operator => null|STR The operator to use for combining
  *                                        (name = value) OPERATOR (name = value); default AND
  *
  * @return mixed int If count, int. If not count, array. false on errors.
  */
 function getEntitiesFromUserSettings(array $options = array())
 {
     if (!isset($options['plugin_id'])) {
         elgg_deprecated_notice("'plugin_id' is now required for elgg_get_entities_from_plugin_user_settings()", 1.9);
         $options['plugin_id'] = elgg_get_calling_plugin_id();
     }
     $singulars = array('plugin_user_setting_name', 'plugin_user_setting_value', 'plugin_user_setting_name_value_pair');
     $options = _elgg_normalize_plural_options_array($options, $singulars);
     // rewrite plugin_user_setting_name_* to the right PS ones.
     $map = array('plugin_user_setting_names' => 'private_setting_names', 'plugin_user_setting_values' => 'private_setting_values', 'plugin_user_setting_name_value_pairs' => 'private_setting_name_value_pairs', 'plugin_user_setting_name_value_pairs_operator' => 'private_setting_name_value_pairs_operator');
     foreach ($map as $plugin => $private) {
         if (!isset($options[$plugin])) {
             continue;
         }
         if (isset($options[$private])) {
             if (!is_array($options[$private])) {
                 $options[$private] = array($options[$private]);
             }
             $options[$private] = array_merge($options[$private], $options[$plugin]);
         } else {
             $options[$private] = $options[$plugin];
         }
     }
     $prefix = _elgg_namespace_plugin_private_setting('user_setting', '', $options['plugin_id']);
     $options['private_setting_name_prefix'] = $prefix;
     return elgg_get_entities_from_private_settings($options);
 }
Exemplo n.º 12
0
/**
 * Get river items
 *
 * @note If using types and subtypes in a query, they are joined with an AND.
 *
 * @param array $options Parameters:
 *   ids                  => INT|ARR River item id(s)
 *   subject_guids        => INT|ARR Subject guid(s)
 *   object_guids         => INT|ARR Object guid(s)
 *   target_guids         => INT|ARR Target guid(s)
 *   annotation_ids       => INT|ARR The identifier of the annotation(s)
 *   action_types         => STR|ARR The river action type(s) identifier
 *   posted_time_lower    => INT     The lower bound on the time posted
 *   posted_time_upper    => INT     The upper bound on the time posted
 *
 *   types                => STR|ARR Entity type string(s)
 *   subtypes             => STR|ARR Entity subtype string(s)
 *   type_subtype_pairs   => ARR     Array of type => subtype pairs where subtype
 *                                   can be an array of subtype strings
 *
 *   relationship         => STR     Relationship identifier
 *   relationship_guid    => INT|ARR Entity guid(s)
 *   inverse_relationship => BOOL    Subject or object of the relationship (false)
 *
 * 	 limit                => INT     Number to show per page (20)
 *   offset               => INT     Offset in list (0)
 *   count                => BOOL    Count the river items? (false)
 *   order_by             => STR     Order by clause (rv.posted desc)
 *   group_by             => STR     Group by clause
 *
 * @return array|int
 * @since 1.8.0
 */
function elgg_get_river(array $options = array())
{
    global $CONFIG;
    $defaults = array('ids' => ELGG_ENTITIES_ANY_VALUE, 'subject_guids' => ELGG_ENTITIES_ANY_VALUE, 'object_guids' => ELGG_ENTITIES_ANY_VALUE, 'target_guids' => ELGG_ENTITIES_ANY_VALUE, 'annotation_ids' => ELGG_ENTITIES_ANY_VALUE, 'action_types' => ELGG_ENTITIES_ANY_VALUE, 'relationship' => null, 'relationship_guid' => null, 'inverse_relationship' => false, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 20, 'offset' => 0, 'count' => false, 'order_by' => 'rv.posted desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'wheres' => array(), 'joins' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('id', 'subject_guid', 'object_guid', 'target_guid', 'annotation_id', 'action_type', 'type', 'subtype');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $wheres = $options['wheres'];
    $wheres[] = _elgg_get_guid_based_where_sql('rv.id', $options['ids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.target_guid', $options['target_guids']);
    $wheres[] = _elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
    $wheres[] = _elgg_river_get_action_where_sql($options['action_types']);
    $wheres[] = _elgg_get_river_type_subtype_where_sql('rv', $options['types'], $options['subtypes'], $options['type_subtype_pairs']);
    if ($options['posted_time_lower'] && is_int($options['posted_time_lower'])) {
        $wheres[] = "rv.posted >= {$options['posted_time_lower']}";
    }
    if ($options['posted_time_upper'] && is_int($options['posted_time_upper'])) {
        $wheres[] = "rv.posted <= {$options['posted_time_upper']}";
    }
    $joins = $options['joins'];
    if ($options['relationship_guid']) {
        $clauses = elgg_get_entity_relationship_where_sql('rv.subject_guid', $options['relationship'], $options['relationship_guid'], $options['inverse_relationship']);
        if ($clauses) {
            $wheres = array_merge($wheres, $clauses['wheres']);
            $joins = array_merge($joins, $clauses['joins']);
        }
    }
    // 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);
    if (!$options['count']) {
        $query = "SELECT DISTINCT rv.* FROM {$CONFIG->dbprefix}river rv ";
    } else {
        $query = "SELECT COUNT(DISTINCT rv.id) AS total FROM {$CONFIG->dbprefix}river rv ";
    }
    // add joins
    foreach ($joins as $j) {
        $query .= " {$j} ";
    }
    // add wheres
    $query .= ' WHERE ';
    foreach ($wheres as $w) {
        $query .= " {$w} AND ";
    }
    $query .= elgg_river_get_access_sql();
    if (!$options['count']) {
        $options['group_by'] = sanitise_string($options['group_by']);
        if ($options['group_by']) {
            $query .= " GROUP BY {$options['group_by']}";
        }
        $options['order_by'] = sanitise_string($options['order_by']);
        $query .= " ORDER BY {$options['order_by']}";
        if ($options['limit']) {
            $limit = sanitise_int($options['limit']);
            $offset = sanitise_int($options['offset'], false);
            $query .= " LIMIT {$offset}, {$limit}";
        }
        $river_items = get_data($query, '_elgg_row_to_elgg_river_item');
        _elgg_prefetch_river_entities($river_items);
        return $river_items;
    } else {
        $total = get_data_row($query);
        return (int) $total->total;
    }
}
Exemplo n.º 13
0
/**
 * Returns options to pass to elgg_get_entities() for metastrings operations.
 *
 * @param string $type    Metastring type: annotation or metadata
 * @param array  $options Options
 *
 * @return array
 * @access private
 */
function _elgg_entities_get_metastrings_options($type, $options)
{
    $valid_types = array('metadata', 'annotation');
    if (!in_array($type, $valid_types)) {
        return false;
    }
    // the options for annotations are singular (annotation_name) but the table
    // is plural (elgg_annotations) so rewrite for the table name.
    $n_table = $type == 'annotation' ? 'annotations' : $type;
    $singulars = array("{$type}_name", "{$type}_value", "{$type}_name_value_pair", "{$type}_owner_guid");
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $clauses = _elgg_get_entity_metadata_where_sql('e', $n_table, $options["{$type}_names"], $options["{$type}_values"], $options["{$type}_name_value_pairs"], $options["{$type}_name_value_pairs_operator"], $options["{$type}_case_sensitive"], $options["order_by_{$type}"], $options["{$type}_owner_guids"]);
    if ($clauses) {
        // merge wheres to pass to elgg_get_entities()
        if (isset($options['wheres']) && !is_array($options['wheres'])) {
            $options['wheres'] = array($options['wheres']);
        } elseif (!isset($options['wheres'])) {
            $options['wheres'] = array();
        }
        $options['wheres'] = array_merge($options['wheres'], $clauses['wheres']);
        // merge joins to pass to elgg_get_entities()
        if (isset($options['joins']) && !is_array($options['joins'])) {
            $options['joins'] = array($options['joins']);
        } elseif (!isset($options['joins'])) {
            $options['joins'] = array();
        }
        $options['joins'] = array_merge($options['joins'], $clauses['joins']);
        if ($clauses['orders']) {
            $order_by_metadata = implode(", ", $clauses['orders']);
            if (isset($options['order_by']) && $options['order_by']) {
                $options['order_by'] = "{$order_by_metadata}, {$options['order_by']}";
            } else {
                $options['order_by'] = "{$order_by_metadata}, e.time_created DESC";
            }
        }
    }
    return $options;
}
Exemplo n.º 14
0
function elgg_solr_get_annotation_ids($options)
{
    $options = _elgg_normalize_metastrings_options($options);
    $type = 'annotations';
    $callback = false;
    $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' => get_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, 'metastring_names' => ELGG_ENTITIES_ANY_VALUE, 'metastring_values' => ELGG_ENTITIES_ANY_VALUE, 'metastring_case_sensitive' => true, 'metastring_calculation' => ELGG_ENTITIES_NO_VALUE, 'metastring_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'metastring_created_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'metastring_owner_guids' => ELGG_ENTITIES_ANY_VALUE, 'metastring_ids' => ELGG_ENTITIES_ANY_VALUE, 'order_by' => 'n_table.time_created ASC, n_table.id ASC', 'limit' => elgg_get_config('default_limit'), 'offset' => 0, 'count' => false, 'selects' => array(), 'wheres' => array(), 'joins' => array(), 'distinct' => true, 'preload_owners' => false, 'callback' => $callback);
    // @todo Ignore site_guid right now because of #2910
    $options['site_guid'] = ELGG_ENTITIES_ANY_VALUE;
    $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', 'type_subtype_pair', 'guid', 'owner_guid', 'container_guid', 'site_guid', 'metastring_name', 'metastring_value', 'metastring_owner_guid', 'metastring_id', 'select', 'where', 'join');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    if (!$options) {
        return false;
    }
    $db_prefix = elgg_get_config('dbprefix');
    // evaluate where clauses
    if (!is_array($options['wheres'])) {
        $options['wheres'] = array($options['wheres']);
    }
    $wheres = $options['wheres'];
    // entities
    $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']);
    $wheres[] = _elgg_get_entity_time_where_sql('n_table', $options['metastring_created_time_upper'], $options['metastring_created_time_lower'], null, null);
    $wheres[] = _elgg_get_guid_based_where_sql('n_table.owner_guid', $options['metastring_owner_guids']);
    // 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']);
    }
    $joins = $options['joins'];
    $joins[] = "JOIN {$db_prefix}entities e ON n_table.entity_guid = e.guid";
    // evaluate selects
    if (!is_array($options['selects'])) {
        $options['selects'] = array($options['selects']);
    }
    $selects = $options['selects'];
    // For performance reasons we don't want the joins required for metadata / annotations
    // unless we're going through one of their callbacks.
    // this means we expect the functions passing different callbacks to pass their required joins.
    // If we're doing a calculation
    $custom_callback = $options['callback'] == 'row_to_elggmetadata' || $options['callback'] == 'row_to_elggannotation';
    $is_calculation = $options['metastring_calculation'] ? true : false;
    if ($custom_callback || $is_calculation) {
        $joins[] = "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id";
        $joins[] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id";
        $selects[] = 'n.string as name';
        $selects[] = 'v.string as value';
    }
    foreach ($joins as $i => $join) {
        if ($join === false) {
            return false;
        } elseif (empty($join)) {
            unset($joins[$i]);
        }
    }
    // metastrings
    $metastring_clauses = _elgg_get_metastring_sql('n_table', $options['metastring_names'], $options['metastring_values'], null, $options['metastring_ids'], $options['metastring_case_sensitive']);
    if ($metastring_clauses) {
        $wheres = array_merge($wheres, $metastring_clauses['wheres']);
        $joins = array_merge($joins, $metastring_clauses['joins']);
    } else {
        $wheres[] = _elgg_get_access_where_sql(array('table_alias' => 'n_table', 'guid_column' => 'entity_guid'));
    }
    $distinct = $options['distinct'] ? "DISTINCT " : "";
    if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {
        $selects = array_unique($selects);
        // evalutate selects
        $select_str = '';
        if ($selects) {
            foreach ($selects as $select) {
                $select_str .= ", {$select}";
            }
        }
        $query = "SELECT {$distinct} n_table.id{$select_str} FROM {$db_prefix}{$type} n_table";
    } elseif ($options['count']) {
        // count is over the entities
        $query = "SELECT count({$distinct} e.guid) as calculation FROM {$db_prefix}{$type} n_table";
    } else {
        $query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}{$type} n_table";
    }
    // remove identical join clauses
    $joins = array_unique($joins);
    // 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(array('table_alias' => 'e'));
    // reverse order by
    if (isset($options['reverse_order_by']) && $options['reverse_order_by']) {
        $options['order_by'] = _elgg_sql_reverse_order_by_clause($options['order_by']);
    }
    if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE && !$options['count']) {
        if (isset($options['group_by'])) {
            $options['group_by'] = sanitise_string($options['group_by']);
            $query .= " GROUP BY {$options['group_by']}";
        }
        if (isset($options['order_by']) && $options['order_by']) {
            $options['order_by'] = sanitise_string($options['order_by']);
            $query .= " ORDER BY {$options['order_by']}, n_table.id";
        }
        if ($options['limit']) {
            $limit = sanitise_int($options['limit']);
            $offset = sanitise_int($options['offset'], false);
            $query .= " LIMIT {$offset}, {$limit}";
        }
        $dt = get_data($query, $options['callback']);
        return $dt;
    } else {
        $result = get_data_row($query);
        return $result->calculation;
    }
}
Exemplo n.º 15
0
/**
 * Get river items
 *
 * @note If using types and subtypes in a query, they are joined with an AND.
 *
 * @param array $options Parameters:
 *   ids                  => INT|ARR River item id(s)
 *   subject_guids        => INT|ARR Subject guid(s)
 *   object_guids         => INT|ARR Object guid(s)
 *   target_guids         => INT|ARR Target guid(s)
 *   annotation_ids       => INT|ARR The identifier of the annotation(s)
 *   action_types         => STR|ARR The river action type(s) identifier
 *   posted_time_lower    => INT     The lower bound on the time posted
 *   posted_time_upper    => INT     The upper bound on the time posted
 *
 *   types                => STR|ARR Entity type string(s)
 *   subtypes             => STR|ARR Entity subtype string(s)
 *   type_subtype_pairs   => ARR     Array of type => subtype pairs where subtype
 *                                   can be an array of subtype strings
 *
 *   relationship         => STR     Relationship identifier
 *   relationship_guid    => INT|ARR Entity guid(s)
 *   inverse_relationship => BOOL    Subject or object of the relationship (false)
 *
 * 	 limit                => INT     Number to show per page (20)
 *   offset               => INT     Offset in list (0)
 *   count                => BOOL    Count the river items? (false)
 *   order_by             => STR     Order by clause (rv.posted desc)
 *   group_by             => STR     Group by clause
 *
 *   distinct             => BOOL    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. (true)
 *
 * @return array|int
 * @since 1.8.0
 */
function elgg_get_group_river(array $options = array())
{
    global $CONFIG;
    //error_log("group river");
    $defaults = array('ids' => ELGG_ENTITIES_ANY_VALUE, 'subject_guids' => ELGG_ENTITIES_ANY_VALUE, 'object_guids' => ELGG_ENTITIES_ANY_VALUE, 'target_guids' => ELGG_ENTITIES_ANY_VALUE, 'annotation_ids' => ELGG_ENTITIES_ANY_VALUE, 'action_types' => ELGG_ENTITIES_ANY_VALUE, 'relationship' => null, 'relationship_guid' => null, 'inverse_relationship' => false, 'types' => ELGG_ENTITIES_ANY_VALUE, 'subtypes' => ELGG_ENTITIES_ANY_VALUE, 'type_subtype_pairs' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'posted_time_upper' => ELGG_ENTITIES_ANY_VALUE, 'limit' => 20, 'offset' => 0, 'count' => false, 'distinct' => false, 'order_by' => 'u.posted desc', 'group_by' => ELGG_ENTITIES_ANY_VALUE, 'wheres' => array(), 'wheres1' => array(), 'wheres2' => array(), 'joins' => array());
    $options = array_merge($defaults, $options);
    $singulars = array('id', 'subject_guid', 'object_guid', 'target_guid', 'annotation_id', 'action_type', 'type', 'subtype');
    $options = _elgg_normalize_plural_options_array($options, $singulars);
    $wheres1 = $options['wheres1'];
    $wheres2 = $options['wheres2'];
    /*
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.id', $options['ids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.subject_guid', $options['subject_guids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.object_guid', $options['object_guids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.target_guid', $options['target_guids']);
    	$wheres[] = _elgg_get_guid_based_where_sql('rv.annotation_id', $options['annotation_ids']);
    	$wheres[] = _elgg_river_get_action_where_sql($options['action_types']);
    	$wheres[] = _elgg_get_river_type_subtype_where_sql('rv', $options['types'],
    		$options['subtypes'], $options['type_subtype_pairs']);
    */
    /*if ($options['posted_time_lower'] && is_int($options['posted_time_lower'])) {
    		$wheres1[] = "rv.posted >= {$options['posted_time_lower']}";
    		$wheres2[] = "rv.posted >= {$options['posted_time_lower']}";
    	}
    
    	if ($options['posted_time_upper'] && is_int($options['posted_time_upper'])) {
    		$wheres1[] = "rv.posted <= {$options['posted_time_upper']}";
    		$wheres2[] = "rv.posted <= {$options['posted_time_upper']}";
    	}*/
    if (!access_get_show_hidden_status()) {
        $wheres1[] = "rv.enabled = 'yes'";
        $wheres2[] = "rv.enabled = 'yes'";
    }
    $dbprefix = elgg_get_config('dbprefix');
    $join1 = "JOIN {$dbprefix}entities oe ON rv.object_guid = oe.guid";
    // LEFT JOIN is used because all river items do not necessarily have target
    $join2 = "LEFT JOIN {$dbprefix}entities te ON rv.target_guid = te.guid";
    // see if any functions failed
    // remove empty strings on successful functions
    /*foreach ($wheres1 as $i => $where) {
    		if ($where === false) {
    			return false;
    		} elseif (empty($where)) {
    			unset($wheres1[$i]);
    		}
    	}
    	foreach ($wheres2 as $i => $where) {
    		if ($where === false) {
    			return false;
    		} elseif (empty($where)) {
    			unset($wheres2[$i]);
    		}
    	}
    
    	// remove identical where clauses
    	$wheres1 = array_unique($wheres1);
    	$wheres2 = array_unique($wheres2);
    	*/
    // Wheres for the 2 parts of the union query
    $w1 = "";
    foreach ($wheres1 as $w) {
        $w1 .= " {$w} AND ";
    }
    $w2 = "";
    foreach ($wheres2 as $w) {
        $w2 .= " {$w} AND ";
    }
    // Make sure that user has access to all the entities referenced by each river item
    $object_access_where = _elgg_get_access_where_sql(array('table_alias' => 'oe'));
    $target_access_where = _elgg_get_access_where_sql(array('table_alias' => 'te'));
    if (!$options['count']) {
        $GOL = "";
        // Group by / order / limit
        $options['group_by'] = sanitise_string($options['group_by']);
        if ($options['group_by']) {
            $GOL .= " GROUP BY {$options['group_by']}";
        }
        $options['order_by'] = sanitise_string($options['order_by']);
        $GOL .= " ORDER BY {$options['order_by']}";
        if ($options['limit']) {
            $limit = sanitise_int($options['limit']);
            $offset = sanitise_int($options['offset'], false);
            $GOL .= " LIMIT {$offset}, {$limit}";
        }
        // custom UNION - based query
        $query = "SELECT u.* FROM ( ( SELECT rv.* FROM {$CONFIG->dbprefix}river rv {$join1} WHERE {$w1} {$object_access_where} ) UNION " . "( SELECT rv.* FROM {$CONFIG->dbprefix}river rv {$join2} WHERE {$w2} ({$target_access_where} OR te.guid IS NULL) ) ) u {$GOL}";
        $river_items = get_data($query, '_elgg_row_to_elgg_river_item');
        _elgg_prefetch_river_entities($river_items);
        //	error_log($query);
        return $river_items;
    } else {
        $query = "SELECT sum(count) as total FROM ( ( SELECT count(*) as count FROM {$CONFIG->dbprefix}river rv {$join1} WHERE {$w1} {$object_access_where} ) UNION " . "( SELECT count(*) as count FROM {$CONFIG->dbprefix}river rv {$join2} WHERE {$w2} ({$target_access_where} OR te.guid IS NULL) ) ) u";
        //	error_log($query);
        $total = get_data_row($query);
        return (int) $total->total;
    }
}