| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 | 
							- <?php
 
- namespace Elgg\Database;
 
- /**
 
-  * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
 
-  *
 
-  * @access private
 
-  *
 
-  * @package    Elgg.Core
 
-  * @subpackage Database
 
-  * @since      1.10.0
 
-  */
 
- class RelationshipsTable {
 
- 	/**
 
- 	 * Global Elgg configuration
 
- 	 * 
 
- 	 * @var \stdClass
 
- 	 */
 
- 	private $CONFIG;
 
- 	/**
 
- 	 * Constructor
 
- 	 */
 
- 	public function __construct() {
 
- 		global $CONFIG;
 
- 		$this->CONFIG = $CONFIG;
 
- 	}
 
- 	/**
 
- 	 * Get a relationship by its ID
 
- 	 *
 
- 	 * @param int $id The relationship ID
 
- 	 *
 
- 	 * @return \ElggRelationship|false False if not found
 
- 	 */
 
- 	function get($id) {
 
- 		$row = _elgg_get_relationship_row($id);
 
- 		if (!$row) {
 
- 			return false;
 
- 		}
 
- 	
 
- 		return new \ElggRelationship($row);
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Get a database row from the relationship table
 
- 	 *
 
- 	 * @param int $id The relationship ID
 
- 	 *
 
- 	 * @return \stdClass|false False if no row found
 
- 	 * @access private
 
- 	 */
 
- 	function getRow($id) {
 
- 		
 
- 	
 
- 		$id = (int)$id;
 
- 	
 
- 		return _elgg_services()->db->getDataRow("SELECT * FROM {$this->CONFIG->dbprefix}entity_relationships WHERE id = $id");
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Delete a relationship by its ID
 
- 	 *
 
- 	 * @param int $id The relationship ID
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	function delete($id) {
 
- 		
 
- 	
 
- 		$id = (int)$id;
 
- 	
 
- 		$relationship = get_relationship($id);
 
- 	
 
- 		if (_elgg_services()->events->trigger('delete', 'relationship', $relationship)) {
 
- 			return _elgg_services()->db->deleteData("DELETE FROM {$this->CONFIG->dbprefix}entity_relationships WHERE id = $id");
 
- 		}
 
- 	
 
- 		return false;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Create a relationship between two entities. E.g. friendship, group membership, site membership.
 
- 	 *
 
- 	 * This function lets you make the statement "$guid_one is a $relationship of $guid_two". In the statement,
 
- 	 * $guid_one is the subject of the relationship, $guid_two is the target, and $relationship is the type.
 
- 	 *
 
- 	 * @param int    $guid_one     GUID of the subject entity of the relationship
 
- 	 * @param string $relationship Type of the relationship
 
- 	 * @param int    $guid_two     GUID of the target entity of the relationship
 
- 	 *
 
- 	 * @return bool
 
- 	 * @throws \InvalidArgumentException
 
- 	 */
 
- 	function add($guid_one, $relationship, $guid_two) {
 
- 		
 
- 	
 
- 		if (strlen($relationship) > \ElggRelationship::RELATIONSHIP_LIMIT) {
 
- 			$msg = "relationship name cannot be longer than " . \ElggRelationship::RELATIONSHIP_LIMIT;
 
- 			throw new \InvalidArgumentException($msg);
 
- 		}
 
- 	
 
- 		$guid_one = (int)$guid_one;
 
- 		$relationship = sanitise_string($relationship);
 
- 		$guid_two = (int)$guid_two;
 
- 		$time = time();
 
- 	
 
- 		// Check for duplicates
 
- 		if (check_entity_relationship($guid_one, $relationship, $guid_two)) {
 
- 			return false;
 
- 		}
 
- 	
 
- 		$id = _elgg_services()->db->insertData("INSERT INTO {$this->CONFIG->dbprefix}entity_relationships
 
- 			(guid_one, relationship, guid_two, time_created)
 
- 			VALUES ($guid_one, '$relationship', $guid_two, $time)");
 
- 	
 
- 		if ($id !== false) {
 
- 			$obj = get_relationship($id);
 
- 	
 
- 			// this event has been deprecated in 1.9. Use 'create', 'relationship'
 
- 			$result_old = _elgg_services()->events->trigger('create', $relationship, $obj);
 
- 	
 
- 			$result = _elgg_services()->events->trigger('create', 'relationship', $obj);
 
- 			if ($result && $result_old) {
 
- 				return true;
 
- 			} else {
 
- 				delete_relationship($obj->id);
 
- 			}
 
- 		}
 
- 	
 
- 		return false;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Check if a relationship exists between two entities. If so, the relationship object is returned.
 
- 	 *
 
- 	 * This function lets you ask "Is $guid_one a $relationship of $guid_two?"
 
- 	 *
 
- 	 * @param int    $guid_one     GUID of the subject entity of the relationship
 
- 	 * @param string $relationship Type of the relationship
 
- 	 * @param int    $guid_two     GUID of the target entity of the relationship
 
- 	 *
 
- 	 * @return \ElggRelationship|false Depending on success
 
- 	 */
 
- 	function check($guid_one, $relationship, $guid_two) {
 
- 		
 
- 	
 
- 		$guid_one = (int)$guid_one;
 
- 		$relationship = sanitise_string($relationship);
 
- 		$guid_two = (int)$guid_two;
 
- 	
 
- 		$query = "SELECT * FROM {$this->CONFIG->dbprefix}entity_relationships
 
- 			WHERE guid_one=$guid_one
 
- 				AND relationship='$relationship'
 
- 				AND guid_two=$guid_two limit 1";
 
- 	
 
- 		$row = row_to_elggrelationship(_elgg_services()->db->getDataRow($query));
 
- 		if ($row) {
 
- 			return $row;
 
- 		}
 
- 	
 
- 		return false;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Delete a relationship between two entities.
 
- 	 *
 
- 	 * This function lets you say "$guid_one is no longer a $relationship of $guid_two."
 
- 	 *
 
- 	 * @param int    $guid_one     GUID of the subject entity of the relationship
 
- 	 * @param string $relationship Type of the relationship
 
- 	 * @param int    $guid_two     GUID of the target entity of the relationship
 
- 	 *
 
- 	 * @return bool
 
- 	 */
 
- 	function remove($guid_one, $relationship, $guid_two) {
 
- 		
 
- 	
 
- 		$guid_one = (int)$guid_one;
 
- 		$relationship = sanitise_string($relationship);
 
- 		$guid_two = (int)$guid_two;
 
- 	
 
- 		$obj = check_entity_relationship($guid_one, $relationship, $guid_two);
 
- 		if ($obj == false) {
 
- 			return false;
 
- 		}
 
- 	
 
- 		// this event has been deprecated in 1.9. Use 'delete', 'relationship'
 
- 		$result_old = _elgg_services()->events->trigger('delete', $relationship, $obj);
 
- 	
 
- 		$result = _elgg_services()->events->trigger('delete', 'relationship', $obj);
 
- 		if ($result && $result_old) {
 
- 			$query = "DELETE FROM {$this->CONFIG->dbprefix}entity_relationships
 
- 				WHERE guid_one = $guid_one
 
- 				AND relationship = '$relationship'
 
- 				AND guid_two = $guid_two";
 
- 	
 
- 			return (bool)_elgg_services()->db->deleteData($query);
 
- 		} else {
 
- 			return false;
 
- 		}
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Removes all relationships originating from a particular entity
 
- 	 *
 
- 	 * @param int    $guid                 GUID of the subject or target entity (see $inverse)
 
- 	 * @param string $relationship         Type of the relationship (optional, default is all relationships)
 
- 	 * @param bool   $inverse_relationship Is $guid the target of the deleted relationships? By default, $guid is the
 
- 	 *                                     subject of the relationships.
 
- 	 * @param string $type                 The type of entity related to $guid (defaults to all)
 
- 	 *
 
- 	 * @return true
 
- 	 */
 
- 	function removeAll($guid, $relationship = "", $inverse_relationship = false, $type = '') {
 
- 		
 
- 	
 
- 		$guid = (int) $guid;
 
- 	
 
- 		if (!empty($relationship)) {
 
- 			$relationship = sanitize_string($relationship);
 
- 			$where = "AND er.relationship = '$relationship'";
 
- 		} else {
 
- 			$where = "";
 
- 		}
 
- 	
 
- 		if (!empty($type)) {
 
- 			$type = sanitize_string($type);
 
- 			if (!$inverse_relationship) {
 
- 				$join = "JOIN {$this->CONFIG->dbprefix}entities e ON e.guid = er.guid_two";
 
- 			} else {
 
- 				$join = "JOIN {$this->CONFIG->dbprefix}entities e ON e.guid = er.guid_one";
 
- 				$where .= " AND ";
 
- 			}
 
- 			$where .= " AND e.type = '$type'";
 
- 		} else {
 
- 			$join = "";
 
- 		}
 
- 	
 
- 		$guid_col = $inverse_relationship ? "guid_two" : "guid_one";
 
- 	
 
- 		_elgg_services()->db->deleteData("
 
- 			DELETE er FROM {$this->CONFIG->dbprefix}entity_relationships AS er
 
- 			$join
 
- 			WHERE $guid_col = $guid
 
- 			$where
 
- 		");
 
- 	
 
- 		return true;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Get all the relationships for a given GUID.
 
- 	 *
 
- 	 * @param int  $guid                 GUID of the subject or target entity (see $inverse)
 
- 	 * @param bool $inverse_relationship Is $guid the target of the deleted relationships? By default $guid is
 
- 	 *                                   the subject of the relationships.
 
- 	 *
 
- 	 * @return \ElggRelationship[]
 
- 	 */
 
- 	function getAll($guid, $inverse_relationship = false) {
 
- 		
 
- 	
 
- 		$guid = (int)$guid;
 
- 	
 
- 		$where = ($inverse_relationship ? "guid_two='$guid'" : "guid_one='$guid'");
 
- 	
 
- 		$query = "SELECT * from {$this->CONFIG->dbprefix}entity_relationships where {$where}";
 
- 	
 
- 		return _elgg_services()->db->getData($query, "row_to_elggrelationship");
 
- 	}
 
- 	
 
- 	/**
 
- 	 * 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);
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Returns SQL appropriate for relationship joins and wheres
 
- 	 *
 
- 	 * @todo add support for multiple relationships and guids.
 
- 	 *
 
- 	 * @param string $column               Column name the GUID should be checked against.
 
- 	 *                                     Provide in table.column format.
 
- 	 * @param string $relationship         Type of the relationship
 
- 	 * @param int    $relationship_guid    Entity GUID to check
 
- 	 * @param bool   $inverse_relationship Is $relationship_guid the target of the relationship?
 
- 	 *
 
- 	 * @return mixed
 
- 	 * @access private
 
- 	 */
 
- 	function getEntityRelationshipWhereSql($column, $relationship = null,
 
- 			$relationship_guid = null, $inverse_relationship = false) {
 
- 	
 
- 		if ($relationship == null && $relationship_guid == null) {
 
- 			return '';
 
- 		}
 
- 		$wheres = array();
 
- 		$joins = array();
 
- 		$group_by = '';
 
- 	
 
- 		if ($inverse_relationship) {
 
- 			$joins[] = "JOIN {$this->CONFIG->dbprefix}entity_relationships r on r.guid_one = $column";
 
- 		} else {
 
- 			$joins[] = "JOIN {$this->CONFIG->dbprefix}entity_relationships r on r.guid_two = $column";
 
- 		}
 
- 	
 
- 		if ($relationship) {
 
- 			$wheres[] = "r.relationship = '" . sanitise_string($relationship) . "'";
 
- 		}
 
- 	
 
- 		if ($relationship_guid) {
 
- 			if ($inverse_relationship) {
 
- 				$wheres[] = "r.guid_two = '$relationship_guid'";
 
- 			} else {
 
- 				$wheres[] = "r.guid_one = '$relationship_guid'";
 
- 			}
 
- 		} else {
 
- 			// See #5775. Queries that do not include a relationship_guid must be grouped by entity table alias,
 
- 			// otherwise the result set is not unique
 
- 			$group_by = $column;
 
- 		}
 
- 	
 
- 		if ($where_str = implode(' AND ', $wheres)) {
 
- 	
 
- 			return array('wheres' => array("($where_str)"), 'joins' => $joins, 'group_by' => $group_by);
 
- 		}
 
- 	
 
- 		return '';
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Gets the number of entities by a the number of entities related to them in a particular way.
 
- 	 * This is a good way to get out the users with the most friends, or the groups with the
 
- 	 * most members.
 
- 	 *
 
- 	 * @param array $options An options array compatible with elgg_get_entities_from_relationship()
 
- 	 *
 
- 	 * @return \ElggEntity[]|int|boolean If count, int. If not count, array. false on errors.
 
- 	 */
 
- 	function getEntitiesFromCount(array $options = array()) {
 
- 		$options['selects'][] = "COUNT(e.guid) as total";
 
- 		$options['group_by'] = 'r.guid_two';
 
- 		$options['order_by'] = 'total desc';
 
- 		return elgg_get_entities_from_relationship($options);
 
- 	}
 
- }
 
 
  |