access_id; } $annotation_id = (int)$annotation_id; $type = $object->getType(); $subtype = $object->getSubtype(); $action_type = sanitise_string($action_type); // Load config global $CONFIG; // Attempt to save river item; return success status $insert_data = insert_data("insert into {$CONFIG->dbprefix}river " . " set type = '{$type}', " . " subtype = '{$subtype}', " . " action_type = '{$action_type}', " . " access_id = {$access_id}, " . " view = '{$view}', " . " subject_guid = {$subject_guid}, " . " object_guid = {$object_guid}, " . " annotation_id = {$annotation_id}, " . " posted = {$posted} "); //update the entities which had the action carried out on it if ($insert_data) { update_entity_last_action($object_guid, $posted); return $insert_data; } } /** * Removes all items relating to a particular acting entity from the river * * @param int $subject_guid The GUID of the entity * * @return bool Depending on success */ function remove_from_river_by_subject($subject_guid) { // Sanitise $subject_guid = (int) $subject_guid; // Load config global $CONFIG; // Remove return delete_data("delete from {$CONFIG->dbprefix}river where subject_guid = {$subject_guid}"); } /** * Removes all items relating to a particular entity being acted upon from the river * * @param int $object_guid The GUID of the entity * * @return bool Depending on success */ function remove_from_river_by_object($object_guid) { // Sanitise $object_guid = (int) $object_guid; // Load config global $CONFIG; // Remove return delete_data("delete from {$CONFIG->dbprefix}river where object_guid = {$object_guid}"); } /** * Removes all items relating to a particular annotation being acted upon from the river * * @param int $annotation_id The ID of the annotation * * @return bool Depending on success * @since 1.7.0 */ function remove_from_river_by_annotation($annotation_id) { // Sanitise $annotation_id = (int) $annotation_id; // Load config global $CONFIG; // Remove return delete_data("delete from {$CONFIG->dbprefix}river where annotation_id = {$annotation_id}"); } /** * Removes a single river entry * * @param int $id The ID of the river entry * * @return bool Depending on success * @since 1.7.2 */ function remove_from_river_by_id($id) { global $CONFIG; // Sanitise $id = (int) $id; return delete_data("delete from {$CONFIG->dbprefix}river where id = {$id}"); } /** * Sets the access ID on river items for a particular object * * @param int $object_guid The GUID of the entity * @param int $access_id The access ID * * @return bool Depending on success */ function update_river_access_by_object($object_guid, $access_id) { // Sanitise $object_guid = (int) $object_guid; $access_id = (int) $access_id; // Load config global $CONFIG; // Remove $query = "update {$CONFIG->dbprefix}river set access_id = {$access_id} where object_guid = {$object_guid}"; return update_data($query); } /** * Retrieves items from the river. All parameters are optional. * * @param int|array $subject_guid Acting entity to restrict to. Default: all * @param int|array $object_guid Entity being acted on to restrict to. Default: all * @param string $subject_relationship If set to a relationship type, this will use * $subject_guid as the starting point and set the * subjects to be all users this * entity has this relationship with (eg 'friend'). * Default: blank * @param string $type The type of entity to restrict to. Default: all * @param string $subtype The subtype of entity to restrict to. Default: all * @param string $action_type The type of river action to restrict to. Default: all * @param int $limit The number of items to retrieve. Default: 20 * @param int $offset The page offset. Default: 0 * @param int $posted_min The minimum time period to look at. Default: none * @param int $posted_max The maximum time period to look at. Default: none * * @return array|false Depending on success */ function get_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '', $type = '', $subtype = '', $action_type = '', $limit = 20, $offset = 0, $posted_min = 0, $posted_max = 0) { // Get config global $CONFIG; // Sanitise variables if (!is_array($subject_guid)) { $subject_guid = (int) $subject_guid; } else { foreach ($subject_guid as $key => $temp) { $subject_guid[$key] = (int) $temp; } } if (!is_array($object_guid)) { $object_guid = (int) $object_guid; } else { foreach ($object_guid as $key => $temp) { $object_guid[$key] = (int) $temp; } } if (!empty($type)) { $type = sanitise_string($type); } if (!empty($subtype)) { $subtype = sanitise_string($subtype); } if (!empty($action_type)) { $action_type = sanitise_string($action_type); } $limit = (int) $limit; $offset = (int) $offset; $posted_min = (int) $posted_min; $posted_max = (int) $posted_max; // Construct 'where' clauses for the river $where = array(); // river table does not have columns expected by get_access_sql_suffix so we modify its output $where[] = str_replace("and enabled='yes'", '', str_replace('owner_guid', 'subject_guid', get_access_sql_suffix())); if (empty($subject_relationship)) { if (!empty($subject_guid)) { if (!is_array($subject_guid)) { $where[] = " subject_guid = {$subject_guid} "; } else { $where[] = " subject_guid in (" . implode(',', $subject_guid) . ") "; } } } else { if (!is_array($subject_guid)) { if ($entities = elgg_get_entities_from_relationship(array ( 'relationship' => $subject_relationship, 'relationship_guid' => $subject_guid, 'limit' => 9999)) ) { $guids = array(); foreach ($entities as $entity) { $guids[] = (int) $entity->guid; } $where[] = " subject_guid in (" . implode(',', $guids) . ") "; } else { return array(); } } } if (!empty($object_guid)) { if (!is_array($object_guid)) { $where[] = " object_guid = {$object_guid} "; } else { $where[] = " object_guid in (" . implode(',', $object_guid) . ") "; } } if (!empty($type)) { $where[] = " type = '{$type}' "; } if (!empty($subtype)) { $where[] = " subtype = '{$subtype}' "; } if (!empty($action_type)) { $where[] = " action_type = '{$action_type}' "; } if (!empty($posted_min)) { $where[] = " posted > {$posted_min} "; } if (!empty($posted_max)) { $where[] = " posted < {$posted_max} "; } $whereclause = implode(' and ', $where); // Construct main SQL $sql = "select id, type, subtype, action_type, access_id, view, subject_guid, object_guid, annotation_id, posted from {$CONFIG->dbprefix}river where {$whereclause} order by posted desc limit {$offset}, {$limit}"; // Get data return get_data($sql); } /** * Retrieves items from the river. All parameters are optional. * * @param int|array $subject_guid Acting entity to restrict to. Default: all * @param int|array $object_guid Entity being acted on to restrict to. Default: all * @param string $subject_relationship If set to a relationship type, this will use * $subject_guid as the starting point and set the * subjects to be all users this entity has this * relationship with (eg 'friend'). Default: blank * @param string $type The type of entity to restrict to. Default: all * @param string $subtype The subtype of entity to restrict to. Default: all * @param string $action_type The type of river action to restrict to. Default: all * @param int $limit The number of items to retrieve. Default: 20 * @param int $offset The page offset. Default: 0 * @param int $posted_min The minimum time period to look at. Default: none * @param int $posted_max The maximum time period to look at. Default: none * * @return array|false Depending on success */ function elgg_get_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '', $type = '', $subtype = '', $action_type = '', $limit = 10, $offset = 0, $posted_min = 0, $posted_max = 0) { // Get config global $CONFIG; // Sanitise variables if (!is_array($subject_guid)) { $subject_guid = (int) $subject_guid; } else { foreach ($subject_guid as $key => $temp) { $subject_guid[$key] = (int) $temp; } } if (!is_array($object_guid)) { $object_guid = (int) $object_guid; } else { foreach ($object_guid as $key => $temp) { $object_guid[$key] = (int) $temp; } } if (!empty($type)) { $type = sanitise_string($type); } if (!empty($subtype)) { $subtype = sanitise_string($subtype); } if (!empty($action_type)) { $action_type = sanitise_string($action_type); } $limit = (int) $limit; $offset = (int) $offset; $posted_min = (int) $posted_min; $posted_max = (int) $posted_max; // Construct 'where' clauses for the river $where = array(); // river table does not have columns expected by get_access_sql_suffix so we modify its output $where[] = str_replace("and enabled='yes'", '', str_replace('owner_guid', 'subject_guid', get_access_sql_suffix_new('er', 'e'))); if (empty($subject_relationship)) { if (!empty($subject_guid)) { if (!is_array($subject_guid)) { $where[] = " subject_guid = {$subject_guid} "; } else { $where[] = " subject_guid in (" . implode(',', $subject_guid) . ") "; } } } else { if (!is_array($subject_guid)) { $entities = elgg_get_entities_from_relationship(array( 'relationship' => $subject_relationship, 'relationship_guid' => $subject_guid, 'limit' => 9999, )); if (is_array($entities) && !empty($entities)) { $guids = array(); foreach ($entities as $entity) { $guids[] = (int) $entity->guid; } // $guids[] = $subject_guid; $where[] = " subject_guid in (" . implode(',', $guids) . ") "; } else { return array(); } } } if (!empty($object_guid)) { if (!is_array($object_guid)) { $where[] = " object_guid = {$object_guid} "; } else { $where[] = " object_guid in (" . implode(',', $object_guid) . ") "; } } if (!empty($type)) { $where[] = " er.type = '{$type}' "; } if (!empty($subtype)) { $where[] = " er.subtype = '{$subtype}' "; } if (!empty($action_type)) { $where[] = " action_type = '{$action_type}' "; } if (!empty($posted_min)) { $where[] = " posted > {$posted_min} "; } if (!empty($posted_max)) { $where[] = " posted < {$posted_max} "; } $whereclause = implode(' and ', $where); // Construct main SQL $sql = "select er.*" . " from {$CONFIG->dbprefix}river er, {$CONFIG->dbprefix}entities e " . " where {$whereclause} AND er.object_guid = e.guid GROUP BY object_guid " . " ORDER BY e.last_action desc LIMIT {$offset}, {$limit}"; // Get data return get_data($sql); } /** * Returns a human-readable representation of a river item * * @see get_river_items * * @param stdClass $item A river item object as returned from get_river_items * * @return string|false Depending on success */ function elgg_view_river_item($item) { if (isset($item->view)) { $object = get_entity($item->object_guid); $subject = get_entity($item->subject_guid); if (!$object || !$subject) { // probably means an entity is disabled return false; } else { if (elgg_view_exists($item->view)) { $body = elgg_view($item->view, array( 'item' => $item )); } } return elgg_view('river/item/wrapper', array( 'item' => $item, 'body' => $body )); } return false; } /** * Returns a human-readable version of the river. * * @param int|array $subject_guid Acting entity to restrict to. Default: all * @param int|array $object_guid Entity being acted on to restrict to. Default: all * @param string $subject_relationship If set to a relationship type, this will use * $subject_guid as the starting point and set * the subjects to be all users this entity has this * relationship with (eg 'friend'). Default: blank * @param string $type The type of entity to restrict to. Default: all * @param string $subtype The subtype of entity to restrict to. Default: all * @param string $action_type The type of river action to restrict to. Default: all * @param int $limit The number of items to retrieve. Default: 20 * @param int $posted_min The minimum time period to look at. Default: none * @param int $posted_max The maximum time period to look at. Default: none * @param bool $pagination Show pagination? * @param $bool $chronological Show in chronological order? * * @return string Human-readable river. */ function elgg_view_river_items($subject_guid = 0, $object_guid = 0, $subject_relationship = '', $type = '', $subtype = '', $action_type = '', $limit = 20, $posted_min = 0, $posted_max = 0, $pagination = true, $chronological = false) { // Get input from outside world and sanitise it $offset = (int) get_input('offset', 0); // Get the correct function if ($chronological == true) { $riveritems = get_river_items($subject_guid, $object_guid, $subject_relationship, $type, $subtype, $action_type, ($limit + 1), $offset, $posted_min, $posted_max); } else { $riveritems = elgg_get_river_items($subject_guid, $object_guid, $subject_relationship, $type, $subtype, $action_type, ($limit + 1), $offset, $posted_min, $posted_max); } // Get river items, if they exist if ($riveritems) { return elgg_view('river/item/list', array( 'limit' => $limit, 'offset' => $offset, 'items' => $riveritems, 'pagination' => $pagination )); } return ''; } /** * This function has been added here until we decide if it is going to roll into core or not * Add access restriction sql code to a given query. * Note that if this code is executed in privileged mode it will return blank. * * @TODO: DELETE once Query classes are fully integrated * * @param string $table_prefix_one Optional table. prefix for the access code. * @param string $table_prefix_two Another optiona table prefix? * @param int $owner Owner GUID * * @return string */ function get_access_sql_suffix_new($table_prefix_one = '', $table_prefix_two = '', $owner = null) { global $ENTITY_SHOW_HIDDEN_OVERRIDE, $CONFIG; $sql = ""; $friends_bit = ""; $enemies_bit = ""; if ($table_prefix_one) { $table_prefix_one = sanitise_string($table_prefix_one) . "."; } if ($table_prefix_two) { $table_prefix_two = sanitise_string($table_prefix_two) . "."; } if (!isset($owner)) { $owner = get_loggedin_userid(); } if (!$owner) { $owner = -1; } $ignore_access = elgg_check_access_overrides($owner); $access = get_access_list($owner); if ($ignore_access) { $sql = " (1 = 1) "; } else if ($owner != -1) { $friends_bit = "{$table_prefix_one}access_id = " . ACCESS_FRIENDS . " AND {$table_prefix_one}owner_guid IN ( SELECT guid_one FROM {$CONFIG->dbprefix}entity_relationships WHERE relationship='friend' AND guid_two=$owner )"; $friends_bit = '(' . $friends_bit . ') OR '; if ((isset($CONFIG->user_block_and_filter_enabled)) && ($CONFIG->user_block_and_filter_enabled)) { // check to see if the user is in the entity owner's block list // or if the entity owner is in the user's filter list // if so, disallow access $enemies_bit = get_annotation_sql('elgg_block_list', "{$table_prefix_one}owner_guid", $owner, false); $enemies_bit = '(' . $enemies_bit . ' AND ' . get_annotation_sql('elgg_filter_list', $owner, "{$table_prefix_one}owner_guid", false) . ')'; } } if (empty($sql)) { $sql = " $friends_bit ({$table_prefix_one}access_id IN {$access} OR ({$table_prefix_one}owner_guid = {$owner}) OR ( {$table_prefix_one}access_id = " . ACCESS_PRIVATE . " AND {$table_prefix_one}owner_guid = $owner ) )"; } if ($enemies_bit) { $sql = "$enemies_bit AND ($sql)"; } if (!$ENTITY_SHOW_HIDDEN_OVERRIDE) { $sql .= " and {$table_prefix_two}enabled='yes'"; } return '(' . $sql . ')'; } /** * Construct and execute the query required for the activity stream. * * @deprecated 1.8 * * @param int $limit Limit the query. * @param int $offset Execute from the given object * @param mixed $type A type, or array of types to look for. * Note: This is how they appear in the SYSTEM LOG. * @param mixed $subtype A subtype, or array of types to look for. * Note: This is how they appear in the SYSTEM LOG. * @param mixed $owner_guid The guid or a collection of GUIDs * @param string $owner_relationship If defined, the relationship between $owner_guid and * the entity owner_guid - so "is $owner_guid $owner_relationship * with $entity->owner_guid" * * @return array An array of system log entries. */ function get_activity_stream_data($limit = 10, $offset = 0, $type = "", $subtype = "", $owner_guid = "", $owner_relationship = "") { global $CONFIG; $limit = (int)$limit; $offset = (int)$offset; if ($type) { if (!is_array($type)) { $type = array(sanitise_string($type)); } else { foreach ($type as $k => $v) { $type[$k] = sanitise_string($v); } } } if ($subtype) { if (!is_array($subtype)) { $subtype = array(sanitise_string($subtype)); } else { foreach ($subtype as $k => $v) { $subtype[$k] = sanitise_string($v); } } } if ($owner_guid) { if (is_array($owner_guid)) { foreach ($owner_guid as $k => $v) { $owner_guid[$k] = (int)$v; } } else { $owner_guid = array((int)$owner_guid); } } $owner_relationship = sanitise_string($owner_relationship); // Get a list of possible views $activity_events = array(); $activity_views = array_merge(elgg_view_tree('activity', 'default'), elgg_view_tree('river', 'default')); $done = array(); foreach ($activity_views as $view) { $fragments = explode('/', $view); $tmp = explode('/', $view, 2); $tmp = $tmp[1]; if ((isset($fragments[0])) && (($fragments[0] == 'river') || ($fragments[0] == 'activity')) && (!in_array($tmp, $done))) { if (isset($fragments[1])) { $f = array(); for ($n = 1; $n < count($fragments); $n++) { $val = sanitise_string($fragments[$n]); switch($n) { case 1: $key = 'type'; break; case 2: $key = 'subtype'; break; case 3: $key = 'event'; break; } $f[$key] = $val; } // Filter result based on parameters $add = true; if ($type) { if (!in_array($f['type'], $type)) { $add = false; } } if (($add) && ($subtype)) { if (!in_array($f['subtype'], $subtype)) { $add = false; } } if (($add) && ($event)) { if (!in_array($f['event'], $event)) { $add = false; } } if ($add) { $activity_events[] = $f; } } $done[] = $tmp; } } $n = 0; foreach ($activity_events as $details) { // Get what we're talking about if ($details['subtype'] == 'default') { $details['subtype'] = ''; } if (($details['type']) && ($details['event'])) { if ($n > 0) { $obj_query .= " or "; } $access = ""; if ($details['type'] != 'relationship') { $access = " and " . get_access_sql_suffix('sl'); } $obj_query .= "( sl.object_type='{$details['type']}' AND sl.object_subtype='{$details['subtype']}' AND sl.event='{$details['event']}' $access )"; $n++; } } // User if ((count($owner_guid)) && ($owner_guid[0] != 0)) { $user = " and sl.performed_by_guid in (" . implode(',', $owner_guid) . ")"; if ($owner_relationship) { $friendsarray = ""; if ($friends = elgg_get_entities_from_relationship(array( 'relationship' => $owner_relationship, 'relationship_guid' => $owner_guid[0], 'inverse_relationship' => FALSE, 'types' => 'user', 'subtypes' => $subtype, 'limit' => 9999)) ) { $friendsarray = array(); foreach ($friends as $friend) { $friendsarray[] = $friend->getGUID(); } $user = " and sl.performed_by_guid in (" . implode(',', $friendsarray) . ")"; } } } $query = "SELECT sl.* FROM {$CONFIG->dbprefix}system_log sl WHERE 1 $user AND ($obj_query) ORDER BY sl.time_created desc limit $offset, $limit"; return get_data($query); }