relationships.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <?php
  2. /**
  3. * Elgg relationships.
  4. *
  5. * @package Elgg.Core
  6. * @subpackage DataModel.Relationship
  7. */
  8. /**
  9. * Convert a database row to a new \ElggRelationship
  10. *
  11. * @param \stdClass $row Database row from the relationship table
  12. *
  13. * @return \ElggRelationship|false
  14. * @access private
  15. */
  16. function row_to_elggrelationship($row) {
  17. if ($row instanceof \stdClass) {
  18. return new \ElggRelationship($row);
  19. }
  20. return false;
  21. }
  22. /**
  23. * Get a relationship by its ID
  24. *
  25. * @param int $id The relationship ID
  26. *
  27. * @return \ElggRelationship|false False if not found
  28. */
  29. function get_relationship($id) {
  30. return _elgg_services()->relationshipsTable->get($id);
  31. }
  32. /**
  33. * Get a database row from the relationship table
  34. *
  35. * @param int $id The relationship ID
  36. *
  37. * @return \stdClass|false False if no row found
  38. * @access private
  39. */
  40. function _elgg_get_relationship_row($id) {
  41. return _elgg_services()->relationshipsTable->getRow($id);
  42. }
  43. /**
  44. * Delete a relationship by its ID
  45. *
  46. * @param int $id The relationship ID
  47. *
  48. * @return bool
  49. */
  50. function delete_relationship($id) {
  51. return _elgg_services()->relationshipsTable->delete($id);
  52. }
  53. /**
  54. * Create a relationship between two entities. E.g. friendship, group membership, site membership.
  55. *
  56. * This function lets you make the statement "$guid_one is a $relationship of $guid_two". In the statement,
  57. * $guid_one is the subject of the relationship, $guid_two is the target, and $relationship is the type.
  58. *
  59. * @param int $guid_one GUID of the subject entity of the relationship
  60. * @param string $relationship Type of the relationship
  61. * @param int $guid_two GUID of the target entity of the relationship
  62. *
  63. * @return bool
  64. * @throws InvalidArgumentException
  65. */
  66. function add_entity_relationship($guid_one, $relationship, $guid_two) {
  67. return _elgg_services()->relationshipsTable->add($guid_one, $relationship, $guid_two);
  68. }
  69. /**
  70. * Check if a relationship exists between two entities. If so, the relationship object is returned.
  71. *
  72. * This function lets you ask "Is $guid_one a $relationship of $guid_two?"
  73. *
  74. * @param int $guid_one GUID of the subject entity of the relationship
  75. * @param string $relationship Type of the relationship
  76. * @param int $guid_two GUID of the target entity of the relationship
  77. *
  78. * @return \ElggRelationship|false Depending on success
  79. */
  80. function check_entity_relationship($guid_one, $relationship, $guid_two) {
  81. return _elgg_services()->relationshipsTable->check($guid_one, $relationship, $guid_two);
  82. }
  83. /**
  84. * Delete a relationship between two entities.
  85. *
  86. * This function lets you say "$guid_one is no longer a $relationship of $guid_two."
  87. *
  88. * @param int $guid_one GUID of the subject entity of the relationship
  89. * @param string $relationship Type of the relationship
  90. * @param int $guid_two GUID of the target entity of the relationship
  91. *
  92. * @return bool
  93. */
  94. function remove_entity_relationship($guid_one, $relationship, $guid_two) {
  95. return _elgg_services()->relationshipsTable->remove($guid_one, $relationship, $guid_two);
  96. }
  97. /**
  98. * Removes all relationships originating from a particular entity
  99. *
  100. * @param int $guid GUID of the subject or target entity (see $inverse)
  101. * @param string $relationship Type of the relationship (optional, default is all relationships)
  102. * @param bool $inverse_relationship Is $guid the target of the deleted relationships? By default, $guid is the
  103. * subject of the relationships.
  104. * @param string $type The type of entity related to $guid (defaults to all)
  105. *
  106. * @return true
  107. */
  108. function remove_entity_relationships($guid, $relationship = "", $inverse_relationship = false, $type = '') {
  109. return _elgg_services()->relationshipsTable->removeAll($guid, $relationship, $inverse_relationship, $type);
  110. }
  111. /**
  112. * Get all the relationships for a given GUID.
  113. *
  114. * @param int $guid GUID of the subject or target entity (see $inverse)
  115. * @param bool $inverse_relationship Is $guid the target of the relationships? By default $guid is
  116. * the subject of the relationships.
  117. *
  118. * @return \ElggRelationship[]
  119. */
  120. function get_entity_relationships($guid, $inverse_relationship = false) {
  121. return _elgg_services()->relationshipsTable->getAll($guid, $inverse_relationship);
  122. }
  123. /**
  124. * Return entities matching a given query joining against a relationship.
  125. *
  126. * By default the function finds relationship targets. E.g.:
  127. *
  128. * // find groups with a particular member:
  129. * $options = [
  130. * 'relationship' => 'member',
  131. * 'relationship_guid' => $member->guid,
  132. * ];
  133. *
  134. * // find people the user has friended
  135. * $options = [
  136. * 'relationship' => 'friend',
  137. * 'relationship_guid' => $user->guid,
  138. * ];
  139. *
  140. * // find stuff created by friends (not in groups)
  141. * $options = [
  142. * 'relationship' => 'friend',
  143. * 'relationship_guid' => $user->guid,
  144. * 'relationship_join_on' => 'container_guid',
  145. * ];
  146. *
  147. * To find relationship subjects, set "inverse_relationship" to true. E.g.:
  148. *
  149. * // find members of a particular group
  150. * $options = [
  151. * 'relationship' => 'member',
  152. * 'relationship_guid' => $group->guid,
  153. * 'inverse_relationship' => true,
  154. * ];
  155. *
  156. * // find users who have friended the current user
  157. * $options = [
  158. * 'relationship' => 'friend',
  159. * 'relationship_guid' => $user->guid,
  160. * 'inverse_relationship' => true,
  161. * ];
  162. *
  163. * @note You may want to specify "type" because relationship types might be used for other entities.
  164. *
  165. * This also accepts all options available to elgg_get_entities() and elgg_get_entities_from_metadata().
  166. *
  167. * To ask for entities that do not have a particular relationship to an entity,
  168. * use a custom where clause like the following:
  169. *
  170. * $options['wheres'][] = "NOT EXISTS (
  171. * SELECT 1 FROM {$db_prefix}entity_relationships
  172. * WHERE guid_one = e.guid
  173. * AND relationship = '$relationship'
  174. * )";
  175. *
  176. * @see elgg_get_entities
  177. * @see elgg_get_entities_from_metadata
  178. *
  179. * @param array $options Array in format:
  180. *
  181. * relationship => null|STR Type of the relationship. E.g. "member"
  182. *
  183. * relationship_guid => null|INT GUID of the subject of the relationship, unless "inverse_relationship" is set
  184. * to true, in which case this will specify the target.
  185. *
  186. * inverse_relationship => false|BOOL Are we searching for relationship subjects? By default, the query finds
  187. * targets of relationships.
  188. *
  189. * relationship_join_on => null|STR How the entities relate: guid (default), container_guid, or owner_guid
  190. * Examples using the relationship 'friend':
  191. * 1. use 'guid' if you want the user's friends
  192. * 2. use 'owner_guid' if you want the entities the user's friends own
  193. * (including in groups)
  194. * 3. use 'container_guid' if you want the entities in the user's personal
  195. * space (non-group)
  196. *
  197. * relationship_created_time_lower => null|INT Relationship created time lower boundary in epoch time
  198. *
  199. * relationship_created_time_upper => null|INT Relationship created time upper boundary in epoch time
  200. *
  201. * @return \ElggEntity[]|mixed If count, int. If not count, array. false on errors.
  202. * @since 1.7.0
  203. */
  204. function elgg_get_entities_from_relationship($options) {
  205. return _elgg_services()->relationshipsTable->getEntities($options);
  206. }
  207. /**
  208. * Returns SQL appropriate for relationship joins and wheres
  209. *
  210. * @todo add support for multiple relationships and guids.
  211. *
  212. * @param string $column Column name the GUID should be checked against.
  213. * Provide in table.column format.
  214. * @param string $relationship Type of the relationship
  215. * @param int $relationship_guid Entity GUID to check
  216. * @param bool $inverse_relationship Is $relationship_guid the target of the relationship?
  217. *
  218. * @return mixed
  219. * @since 1.7.0
  220. * @access private
  221. */
  222. function elgg_get_entity_relationship_where_sql($column, $relationship = null,
  223. $relationship_guid = null, $inverse_relationship = false) {
  224. return _elgg_services()->relationshipsTable->getEntityRelationshipWhereSql(
  225. $column, $relationship, $relationship_guid, $inverse_relationship);
  226. }
  227. /**
  228. * Returns a viewable list of entities by relationship
  229. *
  230. * @param array $options Options array for retrieval of entities
  231. *
  232. * @see elgg_list_entities()
  233. * @see elgg_get_entities_from_relationship()
  234. *
  235. * @return string The viewable list of entities
  236. */
  237. function elgg_list_entities_from_relationship(array $options = array()) {
  238. return elgg_list_entities($options, 'elgg_get_entities_from_relationship');
  239. }
  240. /**
  241. * Gets the number of entities by a the number of entities related to them in a particular way.
  242. * This is a good way to get out the users with the most friends, or the groups with the
  243. * most members.
  244. *
  245. * @param array $options An options array compatible with elgg_get_entities_from_relationship()
  246. *
  247. * @return \ElggEntity[]|int|boolean If count, int. If not count, array. false on errors.
  248. * @since 1.8.0
  249. */
  250. function elgg_get_entities_from_relationship_count(array $options = array()) {
  251. return _elgg_services()->relationshipsTable->getEntitiesFromCount($options);
  252. }
  253. /**
  254. * Returns a list of entities by relationship count
  255. *
  256. * @see elgg_get_entities_from_relationship_count()
  257. *
  258. * @param array $options Options array
  259. *
  260. * @return string
  261. * @since 1.8.0
  262. */
  263. function elgg_list_entities_from_relationship_count($options) {
  264. return elgg_list_entities($options, 'elgg_get_entities_from_relationship_count');
  265. }
  266. /**
  267. * Register relationship unit tests
  268. *
  269. * @param string $hook
  270. * @param string $type
  271. * @param array $tests
  272. * @return array
  273. * @access private
  274. */
  275. function _elgg_relationships_test($hook, $type, $tests) {
  276. global $CONFIG;
  277. $tests[] = $CONFIG->path . 'engine/tests/ElggRelationshipTest.php';
  278. return $tests;
  279. }
  280. /**
  281. * Initialize the relationship library
  282. * @access private
  283. */
  284. function _elgg_relationship_init() {
  285. elgg_register_plugin_hook_handler('unit_test', 'system', '_elgg_relationships_test');
  286. }
  287. return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
  288. $events->registerHandler('init', 'system', '_elgg_relationship_init');
  289. };