Elgg  Version 1.11
NotificationsService.php
Go to the documentation of this file.
1 <?php
2 namespace Elgg\Notifications;
3 
4 use ElggEntity;
5 
16 
17  const QUEUE_NAME = 'notifications';
18 
20  protected $subscriptions;
21 
23  protected $queue;
24 
26  protected $hooks;
27 
29  protected $session;
30 
32  protected $events = array();
33 
35  protected $methods = array();
36 
38  protected $deprHandlers = array();
39 
41  protected $deprSubjects = array();
42 
51  public function __construct(\Elgg\Notifications\SubscriptionsService $subscriptions,
53  $this->subscriptions = $subscriptions;
54  $this->queue = $queue;
55  $this->hooks = $hooks;
56  $this->session = $session;
57  }
58 
63  public function registerEvent($type, $subtype, array $actions = array()) {
64 
65  if (!isset($this->events[$type])) {
66  $this->events[$type] = array();
67  }
68  if (!isset($this->events[$type][$subtype])) {
69  $this->events[$type][$subtype] = array();
70  }
71 
72  $action_list =& $this->events[$type][$subtype];
73  if ($actions) {
74  $action_list = array_unique(array_merge($action_list, $actions));
75  } elseif (!in_array('create', $action_list)) {
76  $action_list[] = 'create';
77  }
78  }
79 
84  public function unregisterEvent($type, $subtype) {
85 
86  if (!isset($this->events[$type]) || !isset($this->events[$type][$subtype])) {
87  return false;
88  }
89 
90  unset($this->events[$type][$subtype]);
91 
92  return true;
93  }
94 
98  public function getEvents() {
99  return $this->events;
100  }
101 
106  public function registerMethod($name) {
107  $this->methods[$name] = $name;
108  }
109 
114  public function unregisterMethod($name) {
115  if (isset($this->methods[$name])) {
116  unset($this->methods[$name]);
117  return true;
118  }
119  return false;
120  }
121 
125  public function getMethods() {
126  return $this->methods;
127  }
128 
138  public function enqueueEvent($action, $type, $object) {
139  if ($object instanceof \ElggData) {
140  $object_type = $object->getType();
141  $object_subtype = $object->getSubtype();
142 
143  $registered = false;
144  if (isset($this->events[$object_type])
145  && isset($this->events[$object_type][$object_subtype])
146  && in_array($action, $this->events[$object_type][$object_subtype])) {
147  $registered = true;
148  }
149 
150  if ($registered) {
151  $params = array(
152  'action' => $action,
153  'object' => $object,
154  );
155  $registered = $this->hooks->trigger('enqueue', 'notification', $params, $registered);
156  }
157 
158  if ($registered) {
159  $this->queue->enqueue(new \Elgg\Notifications\Event($object, $action));
160  }
161  }
162  }
163 
171  public function processQueue($stopTime) {
172 
173  $this->subscriptions->methods = $this->methods;
174 
175  $count = 0;
176 
177  // @todo grab mutex
178 
179  $ia = $this->session->setIgnoreAccess(true);
180 
181  while (time() < $stopTime) {
182  // dequeue notification event
183  $event = $this->queue->dequeue();
184  if (!$event) {
185  break;
186  }
187 
188  // test for usage of the deprecated override hook
189  if ($this->existsDeprecatedNotificationOverride($event)) {
190  continue;
191  }
192 
193  $subscriptions = $this->subscriptions->getSubscriptions($event);
194 
195  // return false to stop the default notification sender
196  $params = array('event' => $event, 'subscriptions' => $subscriptions);
197  if ($this->hooks->trigger('send:before', 'notifications', $params, true)) {
198  $this->sendNotifications($event, $subscriptions);
199  }
200  $this->hooks->trigger('send:after', 'notifications', $params);
201  $count++;
202  }
203 
204  // release mutex
205 
206  $this->session->setIgnoreAccess($ia);
207 
208  return $count;
209  }
210 
219  protected function sendNotifications($event, $subscriptions) {
220 
221  if (!$this->methods) {
222  return 0;
223  }
224 
225  $count = 0;
226  foreach ($subscriptions as $guid => $methods) {
227  foreach ($methods as $method) {
228  if (in_array($method, $this->methods)) {
229  if ($this->sendNotification($event, $guid, $method)) {
230  $count++;
231  }
232  }
233  }
234  }
235  return $count;
236  }
237 
247  protected function sendNotification(\Elgg\Notifications\Event $event, $guid, $method) {
248 
249  $recipient = get_user($guid);
250  if (!$recipient || $recipient->isBanned()) {
251  return false;
252  }
253 
254  // don't notify the creator of the content
255  if ($recipient->getGUID() == $event->getActorGUID()) {
256  return false;
257  }
258 
259  $actor = $event->getActor();
260  $object = $event->getObject();
261  if (!$actor || !$object) {
262  return false;
263  }
264 
265  if (($object instanceof ElggEntity) && !has_access_to_entity($object, $recipient)) {
266  return false;
267  }
268 
269  $language = $recipient->language;
270  $params = array(
271  'event' => $event,
272  'method' => $method,
273  'recipient' => $recipient,
274  'language' => $language,
275  'object' => $object,
276  );
277 
278  $subject = _elgg_services()->translator->translate('notification:subject', array($actor->name), $language);
279  $body = _elgg_services()->translator->translate('notification:body', array($object->getURL()), $language);
280  $notification = new \Elgg\Notifications\Notification($event->getActor(), $recipient, $language, $subject, $body, '', $params);
281 
282  $type = 'notification:' . $event->getDescription();
283  if ($this->hooks->hasHandler('prepare', $type)) {
284  $notification = $this->hooks->trigger('prepare', $type, $params, $notification);
285  } else {
286  // pre Elgg 1.9 notification message generation
287  $notification = $this->getDeprecatedNotificationBody($notification, $event, $method);
288  }
289 
290  if ($this->hooks->hasHandler('send', "notification:$method")) {
291  // return true to indicate the notification has been sent
292  $params = array(
293  'notification' => $notification,
294  'event' => $event,
295  );
296  return $this->hooks->trigger('send', "notification:$method", $params, false);
297  } else {
298  // pre Elgg 1.9 notification handler
299  $userGuid = $notification->getRecipientGUID();
300  $senderGuid = $notification->getSenderGUID();
301  $subject = $notification->subject;
302  $body = $notification->body;
303  $params = $notification->params;
304  return (bool)_elgg_notify_user($userGuid, $senderGuid, $subject, $body, $params, array($method));
305  }
306  }
307 
316  $this->deprHandlers[$method] = $handler;
317  }
318 
325  public function getDeprecatedHandler($method) {
326  if (isset($this->deprHandlers[$method])) {
327  return $this->deprHandlers[$method];
328  } else {
329  return null;
330  }
331  }
332 
339  public function getMethodsAsDeprecatedGlobal() {
340  $data = array();
341  foreach ($this->methods as $method) {
342  $data[$method] = 'empty';
343  }
344  return $data;
345  }
346 
355  protected function getDeprecatedNotificationBody(\Elgg\Notifications\Notification $notification, \Elgg\Notifications\Event $event, $method) {
356  $entity = $event->getObject();
357  $params = array(
358  'entity' => $entity,
359  'to_entity' => $notification->getRecipient(),
360  'method' => $method,
361  );
362  $subject = $this->getDeprecatedNotificationSubject($entity->getType(), $entity->getSubtype());
363  $string = $subject . ": " . $entity->getURL();
364  $body = $this->hooks->trigger('notify:entity:message', $entity->getType(), $params, $string);
365 
366  if ($subject) {
367  $notification->subject = $subject;
368  $notification->body = $body;
369  }
370 
371  return $notification;
372  }
373 
383  if ($type == '') {
384  $type = '__BLANK__';
385  }
386  if ($subtype == '') {
387  $subtype = '__BLANK__';
388  }
389 
390  if (!isset($this->deprSubjects[$type])) {
391  $this->deprSubjects[$type] = array();
392  }
393 
394  $this->deprSubjects[$type][$subtype] = $subject;
395  }
396 
405  if ($type == '') {
406  $type = '__BLANK__';
407  }
408  if ($subtype == '') {
409  $subtype = '__BLANK__';
410  }
411 
412  if (!isset($this->deprSubjects[$type])) {
413  return '';
414  }
415 
416  if (!isset($this->deprSubjects[$type][$subtype])) {
417  return '';
418  }
419 
420  return $this->deprSubjects[$type][$subtype];
421  }
422 
429  protected function existsDeprecatedNotificationOverride(\Elgg\Notifications\Event $event) {
430  $entity = $event->getObject();
431  if (!elgg_instanceof($entity)) {
432  return false;
433  }
434  $params = array(
435  'event' => $event->getAction(),
436  'object_type' => $entity->getType(),
437  'object' => $entity,
438  );
439  $hookresult = $this->hooks->trigger('object:notifications', $entity->getType(), $params, false);
440  if ($hookresult === true) {
441  elgg_deprecated_notice("Using the plugin hook 'object:notifications' has been deprecated by the hook 'send:before', 'notifications'", 1.9);
442  return true;
443  } else {
444  return false;
445  }
446  }
447 }
getDeprecatedNotificationBody(\Elgg\Notifications\Notification $notification,\Elgg\Notifications\Event $event, $method)
Get the notification body using a pre-Elgg 1.9 plugin hook.
sendNotification(\Elgg\Notifications\Event $event, $guid, $method)
Send a notification to a subscriber.
$subject
Definition: exceptions.php:25
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
$method
Definition: form.php:25
$object
Definition: upgrade.php:12
existsDeprecatedNotificationOverride(\Elgg\Notifications\Event $event)
Is someone using the deprecated override.
$data
Definition: opendd.php:13
$ia
Definition: upgrade.php:26
sendNotifications($event, $subscriptions)
Sends the notifications based on subscriptions.
$guid
Removes an admin notice.
getMethodsAsDeprecatedGlobal()
Provides a way to incrementally wean Elgg&#39;s notifications code from the global $NOTIFICATION_HANDLERS...
getDeprecatedHandler($method)
Get a deprecated notification handler callback.
setDeprecatedNotificationSubject($type, $subtype, $subject)
Set message subject for deprecated notification code.
events($event="", $object_type="", $function="", $priority=500, $call=false, $object=null)
Deprecated events core function.
$action
$string
$actions
Definition: user_hover.php:12
$params
Definition: login.php:72
elgg_instanceof($entity, $type=null, $subtype=null, $class=null)
Checks if $entity is an and optionally for type and subtype.
Definition: entities.php:922
Save menu items.
get_user($guid)
Get a user object from a GUID.
Definition: users.php:87
_elgg_services()
Definition: autoloader.php:14
elgg_deprecated_notice($msg, $dep_version, $backtrace_level=1)
Log a notice about deprecated use of a function, view, etc.
Definition: elgglib.php:1006
$type
Definition: add.php:8
enqueueEvent($action, $type, $object)
Add a notification event to the queue.
getDeprecatedNotificationSubject($type, $subtype)
Get the deprecated subject.
__construct(\Elgg\Notifications\SubscriptionsService $subscriptions,\Elgg\Queue\Queue $queue,\Elgg\PluginHooksService $hooks,\ElggSession $session)
Constructor.
if(elgg_in_context('widget')) $count
Definition: pagination.php:20
has_access_to_entity($entity, $user=null)
Can a user access an entity.
Definition: access.php:239
$handler
Definition: add.php:10
$entity
Definition: delete.php:10
$language
$vars[&#39;language&#39;]
Definition: languages.php:6
$subtype
Definition: river.php:12
registerEvent($type, $subtype, array $actions=array())
registerDeprecatedHandler($method, $handler)
Register a deprecated notification handler.
elgg ElggEntity
Definition: ElggEntity.js:16
processQueue($stopTime)
Pull notification events from queue until stop time is reached.
_elgg_notify_user($to, $from, $subject, $message, array $params=null, $methods_override="")
Notify a user via their preferences.