Ejemplo n.º 1
0
/**
 * Return entities matching a given query joining against a relationship.
 * Also accepts all options available to elgg_get_entities() and
 * elgg_get_entities_from_metadata().
 *
 * To ask for entities that do not have a particular relationship to an entity,
 * use a custom where clause like the following:
 *
 * 	$options['wheres'][] = "NOT EXISTS (
 *			SELECT 1 FROM {$db_prefix}entity_relationships
 *				WHERE guid_one = e.guid
 *				AND relationship = '$relationship'
 *		)";
 *
 * @see elgg_get_entities
 * @see elgg_get_entities_from_metadata
 *
 * @param array $options Array in format:
 *
 *  relationship         => null|STR Type of the relationship
 *
 *  relationship_guid    => null|INT GUID of the subject or target entity
 *
 *  inverse_relationship => false|BOOL Is relationship_guid is the target entity of the relationship? By default,
 * 	                        relationship_guid is the subject.
 *
 *  relationship_join_on => null|STR How the entities relate: guid (default), container_guid, or owner_guid
 *                          Add in Elgg 1.9.0. Examples using the relationship 'friend':
 *                          1. use 'guid' if you want the user's friends
 *                          2. use 'owner_guid' if you want the entities the user's friends own (including in groups)
 *                          3. use 'container_guid' if you want the entities in the user's personal space (non-group)
 *
 * @return ElggEntity[]|mixed If count, int. If not count, array. false on errors.
 * @since 1.7.0
 */
function elgg_get_entities_from_relationship($options)
{
    $defaults = array('relationship' => null, 'relationship_guid' => null, 'inverse_relationship' => false, 'relationship_join_on' => 'guid');
    $options = array_merge($defaults, $options);
    $join_column = "e.{$options['relationship_join_on']}";
    $clauses = elgg_get_entity_relationship_where_sql($join_column, $options['relationship'], $options['relationship_guid'], $options['inverse_relationship']);
    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']);
        if (isset($options['selects']) && !is_array($options['selects'])) {
            $options['selects'] = array($options['selects']);
        } elseif (!isset($options['selects'])) {
            $options['selects'] = array();
        }
        $select = array('r.id');
        $options['selects'] = array_merge($options['selects'], $select);
        if (!isset($options['group_by'])) {
            $options['group_by'] = $clauses['group_by'];
        }
    }
    return elgg_get_entities_from_metadata($options);
}
/**
 * Return entities matching a given query joining against a relationship.
 * 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:
 *
 * 	relationship => NULL|STR relationship
 *
 * 	relationship_guid => NULL|INT Guid of relationship to test
 *
 * 	inverse_relationship => BOOL Inverse the relationship
 *
 * @return mixed If count, int. If not count, array. false on errors.
 * @since 1.7.0
 */
function elgg_get_entities_from_relationship($options)
{
    $defaults = array('relationship' => NULL, 'relationship_guid' => NULL, 'inverse_relationship' => FALSE);
    $options = array_merge($defaults, $options);
    $clauses = elgg_get_entity_relationship_where_sql('e.guid', $options['relationship'], $options['relationship_guid'], $options['inverse_relationship']);
    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']);
        if (isset($options['selects']) && !is_array($options['selects'])) {
            $options['selects'] = array($options['selects']);
        } elseif (!isset($options['selects'])) {
            $options['selects'] = array();
        }
        $select = array('r.*');
        $options['selects'] = array_merge($options['selects'], $select);
    }
    return elgg_get_entities_from_metadata($options);
}
Ejemplo n.º 3
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;
    }
}
Ejemplo n.º 4
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)
 *   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, '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', 'annotation_id', 'action_type', 'type', 'subtype');
    $options = elgg_normalise_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.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');
        return $river_items;
    } else {
        $total = get_data_row($query);
        return (int) $total->total;
    }
}
Ejemplo n.º 5
0
 /**
  * Return entities matching a given query joining against a relationship.
  * Also accepts all options available to elgg_get_entities() and
  * elgg_get_entities_from_metadata().
  *
  * To ask for entities that do not have a particular relationship to an entity,
  * use a custom where clause like the following:
  *
  * 	$options['wheres'][] = "NOT EXISTS (
  *			SELECT 1 FROM {$db_prefix}entity_relationships
  *				WHERE guid_one = e.guid
  *				AND relationship = '$relationship'
  *		)";
  *
  * @see elgg_get_entities
  * @see elgg_get_entities_from_metadata
  *
  * @param array $options Array in format:
  *
  *  relationship => null|STR Type of the relationship. E.g. "member"
  *
  *  relationship_guid => null|INT GUID of the subject of the relationship, unless "inverse_relationship" is set
  *                                to true, in which case this will specify the target.
  *
  *  inverse_relationship => false|BOOL Are we searching for relationship subjects? By default, the query finds
  *                                     targets of relationships.
  *
  *  relationship_join_on => null|STR How the entities relate: guid (default), container_guid, or owner_guid
  *                                   Examples using the relationship 'friend':
  *                                   1. use 'guid' if you want the user's friends
  *                                   2. use 'owner_guid' if you want the entities the user's friends own
  *                                      (including in groups)
  *                                   3. use 'container_guid' if you want the entities in the user's personal
  *                                      space (non-group)
  *
  * 	relationship_created_time_lower => null|INT Relationship created time lower boundary in epoch time
  *
  * 	relationship_created_time_upper => null|INT Relationship created time upper boundary in epoch time
  * 
  * @return \ElggEntity[]|mixed If count, int. If not count, array. false on errors.
  */
 function getEntities($options)
 {
     $defaults = array('relationship' => null, 'relationship_guid' => null, 'inverse_relationship' => false, 'relationship_join_on' => 'guid', 'relationship_created_time_lower' => ELGG_ENTITIES_ANY_VALUE, 'relationship_created_time_upper' => ELGG_ENTITIES_ANY_VALUE);
     $options = array_merge($defaults, $options);
     $join_column = "e.{$options['relationship_join_on']}";
     $clauses = elgg_get_entity_relationship_where_sql($join_column, $options['relationship'], $options['relationship_guid'], $options['inverse_relationship']);
     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']);
         // limit based on time created
         $time_wheres = _elgg_get_entity_time_where_sql('r', $options['relationship_created_time_upper'], $options['relationship_created_time_lower']);
         if ($time_wheres) {
             $options['wheres'] = array_merge($options['wheres'], array($time_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']);
         if (isset($options['selects']) && !is_array($options['selects'])) {
             $options['selects'] = array($options['selects']);
         } elseif (!isset($options['selects'])) {
             $options['selects'] = array();
         }
         $select = array('r.id');
         $options['selects'] = array_merge($options['selects'], $select);
         if (!isset($options['group_by'])) {
             $options['group_by'] = $clauses['group_by'];
         }
     }
     return elgg_get_entities_from_metadata($options);
 }
Ejemplo n.º 6
0
function pleio_api_users_with_access_device_token($river)
{
    $list = array();
    $subject = get_entity($river->subject_guid);
    $object = get_entity($river->object_guid);
    $wheres = array();
    $joins = array();
    // don't return same object or subject
    $wheres[] = sprintf("e.guid NOT IN (%d, %d, %d, %d)", $object->guid, $object->owner_guid, $subject->guid, $subject->owner_guid);
    $site_guid = $object->site_guid;
    // override site_guid if object is site_guid
    if ($object instanceof Subsite || $object instanceof ElggSite) {
        $site_guid = $object->guid;
    }
    // add access_id specific wheres to determine possible receivers
    $more = false;
    switch ($object->access_id) {
        case ACCESS_DEFAULT:
        case ACCESS_LOGGED_IN:
        case ACCESS_PUBLIC:
            if ($object->type == "user") {
                //only friends $object->guid
                $more = elgg_get_entity_relationship_where_sql('e.guid', 'friend', $object->guid, 1);
            } elseif ($object && $object->container_guid && $object->container_guid != $object->owner_guid && ($container = get_entity($object->container_guid) && $container instanceof ElggGroup)) {
                // only group $object->container_guid
                $more = elgg_get_entity_relationship_where_sql('e.guid', 'member', $object->container_guid, 1);
            } elseif ($site_guid > 1) {
                //only subsite $site_guid
                $more = elgg_get_entity_relationship_where_sql('e.guid', 'member_of_site', $site_guid, 1);
            } else {
                // pleio has too many users to update everyone, so only friends $object->owner_guid
                $more = elgg_get_entity_relationship_where_sql('e.guid', 'friend', $object->owner_guid, 1);
            }
            break;
        case ACCESS_FRIENDS:
            //only friends $object->owner_guid
            $more = elgg_get_entity_relationship_where_sql('e.guid', 'friend', $object->owner_guid, 1);
            break;
        case ACCESS_PRIVATE:
            return array();
        default:
            $users = get_members_of_access_collection($object->access_id, 1);
            $wheres[] = "e.guid IN (" . implode(", ", $users) . ")";
    }
    if ($more) {
        $wheres = array_merge($wheres, $more["wheres"]);
        $joins = array_merge($joins, $more["joins"]);
    }
    // only select users that have a device_token
    $more = elgg_get_entity_private_settings_where_sql('e', array(), array(), array(array('name' => 'device_token', 'value' => 1, 'operand' => 'IS NOT NULL AND 1 = ')));
    $wheres = array_merge($wheres, $more["wheres"]);
    $joins = array_merge($joins, $more["joins"]);
    $options = array('type' => 'user', 'limit' => 100, 'wheres' => $wheres, 'joins' => $joins, 'site_guid' => ELGG_ENTITIES_ANY_VALUE);
    $users = elgg_get_entities($options);
    foreach ($users as $user) {
        $list[$user->guid] = array("device_token" => $user->getPrivateSetting('device_token'), "device" => $user->getPrivateSetting('device'));
    }
    return $list;
}