/** * 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); }
/** * 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; } }
/** * 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; } }
/** * 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); }
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; }