SubscriptionsService.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. namespace Elgg\Notifications;
  3. /**
  4. * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
  5. *
  6. * @access private
  7. *
  8. * @package Elgg.Core
  9. * @subpackage Notifications
  10. * @since 1.9.0
  11. */
  12. class SubscriptionsService {
  13. /**
  14. * Elgg has historically stored subscriptions as relationships with the prefix 'notify'
  15. */
  16. const RELATIONSHIP_PREFIX = 'notify';
  17. /**
  18. * @var array Array of strings. Delivery names as registered with
  19. * elgg_register_notification_method()
  20. */
  21. public $methods;
  22. /** @var \Elgg\Database */
  23. protected $db;
  24. /**
  25. * Constructor
  26. *
  27. * @param \Elgg\Database $db Database object
  28. * @param array $methods Notification delivery method names
  29. */
  30. public function __construct(\Elgg\Database $db, array $methods = array()) {
  31. $this->db = $db;
  32. $this->methods = $methods;
  33. }
  34. /**
  35. * Get the subscriptions for this notification event
  36. *
  37. * The return array is of the form:
  38. *
  39. * array(
  40. * <user guid> => array('email', 'sms', 'ajax'),
  41. * );
  42. *
  43. * @param \Elgg\Notifications\Event $event Notification event
  44. * @return array
  45. */
  46. public function getSubscriptions(\Elgg\Notifications\Event $event) {
  47. $subscriptions = array();
  48. if (!$this->methods) {
  49. return $subscriptions;
  50. }
  51. $object = $event->getObject();
  52. if (!$object) {
  53. return $subscriptions;
  54. }
  55. $prefixLength = strlen(self::RELATIONSHIP_PREFIX);
  56. $records = $this->getSubscriptionRecords($object->getContainerGUID());
  57. foreach ($records as $record) {
  58. $deliveryMethods = explode(',', $record->methods);
  59. $subscriptions[$record->guid] = substr_replace($deliveryMethods, '', 0, $prefixLength);
  60. }
  61. $params = array('event' => $event);
  62. return _elgg_services()->hooks->trigger('get', 'subscriptions', $params, $subscriptions);
  63. }
  64. /**
  65. * Get the subscriptions for the content created inside this container.
  66. *
  67. * The return array is of the form:
  68. *
  69. * array(
  70. * <user guid> => array('email', 'sms', 'ajax'),
  71. * );
  72. *
  73. * @param int $container_guid GUID of the entity acting as a container
  74. * @return array User GUIDs (keys) and their subscription types (values).
  75. */
  76. public function getSubscriptionsForContainer($container_guid) {
  77. $subscriptions = array();
  78. if (!$this->methods) {
  79. return $subscriptions;
  80. }
  81. $prefixLength = strlen(self::RELATIONSHIP_PREFIX);
  82. $records = $this->getSubscriptionRecords($container_guid);
  83. foreach ($records as $record) {
  84. $deliveryMethods = explode(',', $record->methods);
  85. $subscriptions[$record->guid] = substr_replace($deliveryMethods, '', 0, $prefixLength);
  86. }
  87. return $subscriptions;
  88. }
  89. /**
  90. * Subscribe a user to notifications about a target entity
  91. *
  92. * This method will return false if the subscription already exists.
  93. *
  94. * @param int $userGuid The GUID of the user to subscribe to notifications
  95. * @param string $method The delivery method of the notifications
  96. * @param int $targetGuid The entity to receive notifications about
  97. * @return boolean
  98. */
  99. public function addSubscription($userGuid, $method, $targetGuid) {
  100. if (!in_array($method, $this->methods)) {
  101. return false;
  102. }
  103. $prefix = self::RELATIONSHIP_PREFIX;
  104. return add_entity_relationship($userGuid, "$prefix$method", $targetGuid);
  105. }
  106. /**
  107. * Unsubscribe a user to notifications about a target entity
  108. *
  109. * @param int $userGuid The GUID of the user to unsubscribe to notifications
  110. * @param string $method The delivery method of the notifications to stop
  111. * @param int $targetGuid The entity to stop receiving notifications about
  112. * @return boolean
  113. */
  114. public function removeSubscription($userGuid, $method, $targetGuid) {
  115. $prefix = self::RELATIONSHIP_PREFIX;
  116. return remove_entity_relationship($userGuid, "$prefix$method", $targetGuid);
  117. }
  118. /**
  119. * Get subscription records from the database
  120. *
  121. * Records are an object with two vars: guid and methods with the latter
  122. * being a comma-separated list of subscription relationship names.
  123. *
  124. * @param int $container_guid The GUID of the subscription target
  125. * @return array
  126. */
  127. protected function getSubscriptionRecords($container_guid) {
  128. $container_guid = $this->db->sanitizeInt($container_guid);
  129. // create IN clause
  130. $rels = $this->getMethodRelationships();
  131. if (!$rels) {
  132. return array();
  133. }
  134. array_walk($rels, array($this->db, 'sanitizeString'));
  135. $methods_string = "'" . implode("','", $rels) . "'";
  136. $db_prefix = $this->db->getTablePrefix();
  137. $query = "SELECT guid_one AS guid, GROUP_CONCAT(relationship SEPARATOR ',') AS methods
  138. FROM {$db_prefix}entity_relationships
  139. WHERE guid_two = $container_guid AND
  140. relationship IN ($methods_string) GROUP BY guid_one";
  141. return $this->db->getData($query);
  142. }
  143. /**
  144. * Get the relationship names for notifications
  145. *
  146. * @return array
  147. */
  148. protected function getMethodRelationships() {
  149. $prefix = self::RELATIONSHIP_PREFIX;
  150. $names = array();
  151. foreach ($this->methods as $method) {
  152. $names[] = "$prefix$method";
  153. }
  154. return $names;
  155. }
  156. }