notification.php ➔ elgg_send_email()   D
last analyzed

Complexity

Conditions 15
Paths 163

Size

Total Lines 90

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 0
Metric Value
cc 15
nc 163
nop 5
dl 0
loc 90
ccs 0
cts 59
cp 0
crap 240
rs 4.5315
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Adding a New Notification Event
4
 * ===============================
5
 * 1. Register the event with elgg_register_notification_event()
6
 * 
7
 * 2. Register for the notification message plugin hook:
8
 *    'prepare', 'notification:[event name]'. The event name is of the form 
9
 *    [action]:[type]:[subtype]. For example, the publish event for a blog 
10
 *    would be named 'publish:object:blog'.
11
 * 
12
 *    The parameter array for the plugin hook has the keys 'event', 'method',
13
 *    'recipient', and 'language'. The event is an \Elgg\Notifications\Event 
14
 *    object and can provide access to the original object of the event through 
15
 *    the method getObject() and the original actor through getActor().
16
 * 
17
 *    The plugin hook callback modifies and returns a 
18
 *    \Elgg\Notifications\Notification object that holds the message content.
19
 *
20
 *
21
 * Adding a Delivery Method
22
 * =========================
23
 * 1. Register the delivery method name with elgg_register_notification_method()
24
 * 
25
 * 2. Register for the plugin hook for sending notifications:
26
 *    'send', 'notification:[method name]'. It receives the notification object 
27
 *    of the namespace Elgg\Notifications;
28
29
class Notification in the params array with the 
30
 *    key 'notification'. The callback should return a boolean to indicate whether 
31
 *    the message was sent.
32
 * 
33
 * 
34
 * Subscribing a User for Notifications
35
 * ====================================
36
 * Users subscribe to receive notifications based on container and delivery method.
37
 * 
38
 * 
39
 * @package Elgg.Core
40
 * @subpackage Notifications
41
 */
42
43
/**
44
 * Register a notification event
45
 *
46
 * Elgg sends notifications for the items that have been registered with this
47
 * function. For example, if you want notifications to be sent when a bookmark
48
 * has been created or updated, call the function like this:
49
 *
50
 * 	   elgg_register_notification_event('object', 'bookmarks', array('create', 'update'));
51
 *
52
 * @param string $object_type    'object', 'user', 'group', 'site'
53
 * @param string $object_subtype The subtype or name of the entity
54
 * @param array  $actions        Array of actions or empty array for the action event.
55
 *                                An event is usually described by the first string passed
56
 *                                to elgg_trigger_event(). Examples include
57
 *                                'create', 'update', and 'publish'. The default is 'create'.
58
 * @return void
59
 * @since 1.9
60
 */
61
function elgg_register_notification_event($object_type, $object_subtype, array $actions = array()) {
62
	_elgg_services()->notifications->registerEvent($object_type, $object_subtype, $actions);
63
}
64
65
/**
66
 * Unregister a notification event
67
 *
68
 * @param string $object_type    'object', 'user', 'group', 'site'
69
 * @param string $object_subtype The type of the entity
70
 * @return bool
71
 * @since 1.9
72
 */
73
function elgg_unregister_notification_event($object_type, $object_subtype) {
74
	return _elgg_services()->notifications->unregisterEvent($object_type, $object_subtype);
75
}
76
77
/**
78
 * Register a delivery method for notifications
79
 * 
80
 * Register for the 'send', 'notification:[method name]' plugin hook to handle
81
 * sending a notification. A notification object is in the params array for the
82
 * hook with the key 'notification'. See \Elgg\Notifications\Notification.
83
 *
84
 * @param string $name The notification method name
85
 * @return void
86
 * @see elgg_unregister_notification_method()
87
 * @since 1.9
88
 */
89
function elgg_register_notification_method($name) {
90
	_elgg_services()->notifications->registerMethod($name);
91
}
92
93
/**
94
 * Unregister a delivery method for notifications
95
 *
96
 * @param string $name The notification method name
97
 * @return bool
98
 * @see elgg_register_notification_method()
99
 * @since 1.9
100
 */
101
function elgg_unregister_notification_method($name) {
102
	return _elgg_services()->notifications->unregisterMethod($name);
103
}
104
105
/**
106
 * Subscribe a user to notifications about a target entity
107
 *
108
 * @param int    $user_guid   The GUID of the user to subscribe to notifications
109
 * @param string $method      The delivery method of the notifications
110
 * @param int    $target_guid The entity to receive notifications about
111
 * @return bool
112
 * @since 1.9
113
 */
114 View Code Duplication
function elgg_add_subscription($user_guid, $method, $target_guid) {
115
	$methods = _elgg_services()->notifications->getMethods();
116
	$db = _elgg_services()->db;
117
	$subs = new \Elgg\Notifications\SubscriptionsService($db, $methods);
118
	return $subs->addSubscription($user_guid, $method, $target_guid);
119
}
120
121
/**
122
 * Unsubscribe a user to notifications about a target entity
123
 *
124
 * @param int    $user_guid   The GUID of the user to unsubscribe to notifications
125
 * @param string $method      The delivery method of the notifications to stop
126
 * @param int    $target_guid The entity to stop receiving notifications about
127
 * @return bool
128
 * @since 1.9
129
 */
130 View Code Duplication
function elgg_remove_subscription($user_guid, $method, $target_guid) {
131
	$methods = _elgg_services()->notifications->getMethods();
132
	$db = _elgg_services()->db;
133
	$subs = new \Elgg\Notifications\SubscriptionsService($db, $methods);
134
	return $subs->removeSubscription($user_guid, $method, $target_guid);
135
}
136
137
/**
138
 * Get the subscriptions for the content created inside this container.
139
 *
140
 * The return array is of the form:
141
 *
142
 * array(
143
 *     <user guid> => array('email', 'sms', 'ajax'),
144
 * );
145
 *
146
 * @param int $container_guid GUID of the entity acting as a container
147
 * @return array User GUIDs (keys) and their subscription types (values).
148
 * @since 1.9
149
 * @todo deprecate once new subscriptions system has been added
150
 */
151 View Code Duplication
function elgg_get_subscriptions_for_container($container_guid) {
152
	$methods = _elgg_services()->notifications->getMethods();
153
	$db = _elgg_services()->db;
154
	$subs = new \Elgg\Notifications\SubscriptionsService($db, $methods);
155
	return $subs->getSubscriptionsForContainer($container_guid);
156
}
157
158
/**
159
 * Queue a notification event for later handling
160
 *
161
 * Checks to see if this event has been registered for notifications.
162
 * If so, it adds the event to a notification queue.
163
 *
164
 * This function triggers the 'enqueue', 'notification' hook.
165
 *
166
 * @param string   $action The name of the action
167
 * @param string   $type   The type of the object
168
 * @param \ElggData $object The object of the event
169
 * @return void
170
 * @access private
171
 * @since 1.9
172
 */
173
function _elgg_enqueue_notification_event($action, $type, $object) {
174
	_elgg_services()->notifications->enqueueEvent($action, $type, $object);
175
}
176
177
/**
178
 * @access private
179
 */
180
function _elgg_notifications_cron() {
181
	// calculate when we should stop
182
	// @todo make configurable?
183
	$stop_time = time() + 45;
184
	_elgg_services()->notifications->processQueue($stop_time);
185
}
186
187
/**
188
 * Send an email notification
189
 * 
190
 * @param string $hook   Hook name
191
 * @param string $type   Hook type
192
 * @param bool   $result Has anyone sent a message yet?
193
 * @param array  $params Hook parameters
194
 * @return bool
195
 * @access private
196
 */
197
function _elgg_send_email_notification($hook, $type, $result, $params) {
198
	
199
	if ($result === true) {
200
		// assume someone else already sent the message
201
		return;
202
	}
203
	
204
	/* @var \Elgg\Notifications\Notification $message */
205
	$message = $params['notification'];
206
207
	$sender = $message->getSender();
208
	$recipient = $message->getRecipient();
209
210
	if (!$sender) {
211
		return false;
212
	}
213
214
	if (!$recipient || !$recipient->email) {
215
		return false;
216
	}
217
218
	$to = $recipient->email;
219
220
	$site = elgg_get_site_entity();
221
	// If there's an email address, use it - but only if it's not from a user.
222
	if (!($sender instanceof \ElggUser) && $sender->email) {
223
		$from = $sender->email;
224
	} else if ($site->email) {
225
		$from = $site->email;
226
	} else {
227
		// If all else fails, use the domain of the site.
228
		$from = 'noreply@' . $site->getDomain();
229
	}
230
231
	return elgg_send_email($from, $to, $message->subject, $message->body, $params);
232
}
233
234
/**
235
 * Adds default Message-ID header to all e-mails
236
 *
237
 * @param string $hook        Equals to 'email'
238
 * @param string $type        Equals to 'system'
239
 * @param array  $returnvalue Array containing fields: 'to', 'from', 'subject', 'body', 'headers', 'params'
240
 * @param array  $params      The same value as $returnvalue
241
 * 
242
 * @see https://tools.ietf.org/html/rfc5322#section-3.6.4
243
 * 
244
 * @return array
245
 * 
246
 * @access private
247
 */
248
function _elgg_notifications_smtp_default_message_id_header($hook, $type, $returnvalue, $params) {
249
	
250
	if (!is_array($returnvalue) || !is_array($returnvalue['params'])) {
251
		// another hook handler returned a non-array, let's not override it
252
		return;
253
	}
254
	
255
	$hostname = parse_url(elgg_get_site_url(), PHP_URL_HOST);
256
	$url_path = parse_url(elgg_get_site_url(), PHP_URL_PATH);
257
	
258
	$mt = microtime(true);
259
	
260
	$returnvalue['headers']['Message-ID'] = "<{$url_path}.default.{$mt}@{$hostname}>";
261
	
262
	return $returnvalue;
263
}
264
/**
265
 * Adds default thread SMTP headers to group messages correctly.
266
 * Note that it won't be sufficient for some email clients. Ie. Gmail is looking at message subject anyway.
267
 *
268
 * @param string $hook        Equals to 'email'
269
 * @param string $type        Equals to 'system'
270
 * @param array  $returnvalue Array containing fields: 'to', 'from', 'subject', 'body', 'headers', 'params'
271
 * @param array  $params      The same value as $returnvalue
272
 * @return array
273
 * @access private
274
 */
275
function _elgg_notifications_smtp_thread_headers($hook, $type, $returnvalue, $params) {
276
277
	if (!is_array($returnvalue) || !is_array($returnvalue['params'])) {
278
		// another hook handler returned a non-array, let's not override it
279
		return;
280
	}
281
	
282
	$notificationParams = elgg_extract('params', $returnvalue, array());
283
	/** @var \Elgg\Notifications\Notification */
284
	$notification = elgg_extract('notification', $notificationParams);
285
286
	if (!($notification instanceof \Elgg\Notifications\Notification)) {
287
		return $returnvalue;
288
	}
289
290
	$hostname = parse_url(elgg_get_site_url(), PHP_URL_HOST);
291
	$urlPath = parse_url(elgg_get_site_url(), PHP_URL_PATH);
292
293
	$object = elgg_extract('object', $notification->params);
294
	/** @var \Elgg\Notifications\Event $event */
295
	$event = elgg_extract('event', $notification->params);
296
297
	if (($object instanceof \ElggEntity) && ($event instanceof \Elgg\Notifications\Event)) {
298
		if ($event->getAction() === 'create') {
299
			// create event happens once per entity and we need to guarantee message id uniqueness
300
			// and at the same time have thread message id that we don't need to store
301
			$messageId = "<{$urlPath}.entity.{$object->guid}@{$hostname}>";
302
		} else {
303
			$mt = microtime(true);
304
			$messageId = "<{$urlPath}.entity.{$object->guid}.$mt@{$hostname}>";
305
		}
306
		$returnvalue['headers']["Message-ID"] = $messageId;
307
		$container = $object->getContainerEntity();
308
309
		// let's just thread comments by default
310
		if (($container instanceof \ElggEntity) && ($object instanceof \ElggComment)) {
311
312
			$threadMessageId = "<{$urlPath}.entity.{$container->guid}@{$hostname}>";
313
			$returnvalue['headers']['In-Reply-To'] = $threadMessageId;
314
			$returnvalue['headers']['References'] = $threadMessageId;
315
		}
316
	}
317
318
	return $returnvalue;
319
}
320
321
/**
322
 * @access private
323
 */
324 View Code Duplication
function _elgg_notifications_init() {
325
	elgg_register_plugin_hook_handler('cron', 'minute', '_elgg_notifications_cron', 100);
326
	elgg_register_event_handler('all', 'all', '_elgg_enqueue_notification_event');
327
328
	// add email notifications
329
	elgg_register_notification_method('email');
330
	elgg_register_plugin_hook_handler('send', 'notification:email', '_elgg_send_email_notification');
331
	elgg_register_plugin_hook_handler('email', 'system', '_elgg_notifications_smtp_default_message_id_header', 1);
332
	elgg_register_plugin_hook_handler('email', 'system', '_elgg_notifications_smtp_thread_headers');
333
334
	// add ability to set personal notification method
335
	elgg_extend_view('forms/account/settings', 'core/settings/account/notifications');
336
	elgg_register_plugin_hook_handler('usersettings:save', 'user', '_elgg_save_notification_user_settings');
337
}
338
339
/**
340
 * Notify a user via their preferences.
341
 *
342
 * @param mixed  $to               Either a guid or an array of guid's to notify.
343
 * @param int    $from             GUID of the sender, which may be a user, site or object.
344
 * @param string $subject          Message subject.
345
 * @param string $message          Message body.
346
 * @param array  $params           Misc additional parameters specific to various methods.
347
 * @param mixed  $methods_override A string, or an array of strings specifying the delivery
348
 *                                 methods to use - or leave blank for delivery using the
349
 *                                 user's chosen delivery methods.
350
 *
351
 * @return array Compound array of each delivery user/delivery method's success or failure.
352
 * @access private
353
 */
354
function _elgg_notify_user($to, $from, $subject, $message, array $params = null, $methods_override = "") {
355
356
	$notify_service = _elgg_services()->notifications;
357
358
	// Sanitise
359
	if (!is_array($to)) {
360
		$to = array((int)$to);
361
	}
362
	$from = (int)$from;
363
	//$subject = sanitise_string($subject);
364
365
	// Get notification methods
366
	if (($methods_override) && (!is_array($methods_override))) {
367
		$methods_override = array($methods_override);
368
	}
369
370
	$result = array();
371
372
	foreach ($to as $guid) {
373
		// Results for a user are...
374
		$result[$guid] = array();
375
376
		if ($guid) { // Is the guid > 0?
377
			// Are we overriding delivery?
378
			$methods = $methods_override;
379 View Code Duplication
			if (!$methods) {
380
				$tmp = get_user_notification_settings($guid);
381
				$methods = array();
382
				// $tmp may be false. don't cast
383
				if (is_object($tmp)) {
384
					foreach ($tmp as $k => $v) {
0 ignored issues
show
Bug introduced by
The expression $tmp of type object<stdClass> is not traversable.
Loading history...
385
						// Add method if method is turned on for user!
386
						if ($v) {
387
							$methods[] = $k;
388
						}
389
					}
390
				}
391
			}
392
393
			if ($methods) {
394
				// Deliver
395
				foreach ($methods as $method) {
396
					
397
					$handler = $notify_service->getDeprecatedHandler($method);
398
					/* @var callable $handler */
399
					if (!$handler || !is_callable($handler)) {
400
						elgg_log("No handler registered for the method $method", 'WARNING');
401
						continue;
402
					}
403
404
					elgg_log("Sending message to $guid using $method");
405
406
					// Trigger handler and retrieve result.
407
					try {
408
						$result[$guid][$method] = call_user_func($handler,
409
							$from ? get_entity($from) : null,
410
							get_entity($guid),
411
							$subject,
412
							$message,
413
							$params
414
						);
415
					} catch (Exception $e) {
416
						error_log($e->getMessage());
417
					}
418
				}
419
			}
420
		}
421
	}
422
423
	return $result;
424
}
425
426
427
/**
428
 * Notifications
429
 * This file contains classes and functions which allow plugins to register and send notifications.
430
 *
431
 * There are notification methods which are provided out of the box
432
 * (see notification_init() ). Each method is identified by a string, e.g. "email".
433
 *
434
 * To register an event use register_notification_handler() and pass the method name and a
435
 * handler function.
436
 *
437
 * To send a notification call notify() passing it the method you wish to use combined with a
438
 * number of method specific addressing parameters.
439
 *
440
 * Catch NotificationException to trap errors.
441
 *
442
 * @package Elgg.Core
443
 * @subpackage Notifications
444
 */
445
446
447
/**
448
 * Notify a user via their preferences.
449
 *
450
 * @param mixed  $to               Either a guid or an array of guid's to notify.
451
 * @param int    $from             GUID of the sender, which may be a user, site or object.
452
 * @param string $subject          Message subject.
453
 * @param string $message          Message body.
454
 * @param array  $params           Misc additional parameters specific to various methods.
455
 *
456
 *                                 By default Elgg core supports three parameters, which give
457
 *                                 notification plugins more control over the notifications:
458
 *
459
 *                                 object => null|\ElggEntity|\ElggAnnotation The object that
460
 *                                           is triggering the notification.
461
 *
462
 *                                 action => null|string Word that describes the action that
463
 *                                           is triggering the notification (e.g. "create"
464
 *                                           or "update").
465
 *
466
 *                                 summary => null|string Summary that notification plugins
467
 *                                            can use alongside the notification title and body.
468
 *
469
 * @param mixed  $methods_override A string, or an array of strings specifying the delivery
470
 *                                 methods to use - or leave blank for delivery using the
471
 *                                 user's chosen delivery methods.
472
 *
473
 * @return array Compound array of each delivery user/delivery method's success or failure.
474
 * @throws NotificationException
475
 */
476
function notify_user($to, $from, $subject, $message, array $params = array(), $methods_override = "") {
477
478
	if (!is_array($to)) {
479
		$to = array((int)$to);
480
	}
481
	$from = (int)$from;
482
	$from = get_entity($from) ? $from : elgg_get_site_entity()->guid;
483
	$sender = get_entity($from);
484
	$summary = elgg_extract('summary', $params, '');
485
486
	// Get notification methods
487
	if (($methods_override) && (!is_array($methods_override))) {
488
		$methods_override = array($methods_override);
489
	}
490
491
	$result = array();
492
493
	$available_methods = _elgg_services()->notifications->getMethods();
494
	if (!$available_methods) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $available_methods of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
495
		// There are no notifications methods to use
496
		return $result;
497
	}
498
499
	// temporary backward compatibility for 1.8 and earlier notifications
500
	$event = null;
501
	if (isset($params['object']) && isset($params['action'])) {
502
		$event = new \Elgg\Notifications\Event($params['object'], $params['action'], $sender);
503
	}
504
	$params['event'] = $event;
505
506
	foreach ($to as $guid) {
507
		// Results for a user are...
508
		$result[$guid] = array();
509
510
		if ($guid) { // Is the guid > 0?
511
			// Are we overriding delivery?
512
			$methods = $methods_override;
513 View Code Duplication
			if (!$methods) {
514
				$tmp = (array)get_user_notification_settings($guid);
515
				$methods = array();
516
				foreach ($tmp as $k => $v) {
517
					// Add method if method is turned on for user!
518
					if ($v) {
519
						$methods[] = $k;
520
					}
521
				}
522
			}
523
524
			if ($methods) {
525
				// Deliver
526
				foreach ($methods as $method) {
527
					if (!in_array($method, $available_methods)) {
528
						// This method was available the last time the user saved their
529
						// notification settings. It's however currently disabled.
530
						continue;
531
					}
532
533
					if (_elgg_services()->hooks->hasHandler('send', "notification:$method")) {
534
						// 1.9 style notification handler
535
						$recipient = get_entity($guid);
536
						if (!$recipient) {
537
							continue;
538
						}
539
						$language = $recipient->language;
540
						$notification = new \Elgg\Notifications\Notification($sender, $recipient, $language, $subject, $message, $summary, $params);
541
						$params['notification'] = $notification;
542
						$result[$guid][$method] = _elgg_services()->hooks->trigger('send', "notification:$method", $params, false);
543
					} else {
544
						$result[$guid][$method] = _elgg_notify_user($guid, $from, $subject, $message, $params, array($method));
545
					}
546
				}
547
			}
548
		}
549
	}
550
551
	return $result;
552
}
553
554
/**
555
 * Get the notification settings for a given user.
556
 *
557
 * @param int $user_guid The user id
558
 *
559
 * @return \stdClass|false
560
 */
561
function get_user_notification_settings($user_guid = 0) {
562
	$user_guid = (int)$user_guid;
563
564
	if ($user_guid == 0) {
565
		$user_guid = elgg_get_logged_in_user_guid();
566
	}
567
568
	// @todo: there should be a better way now that metadata is cached. E.g. just query for MD names, then
569
	// query user object directly
570
	$all_metadata = elgg_get_metadata(array(
571
		'guid' => $user_guid,
572
		'limit' => 0
573
	));
574
	if ($all_metadata) {
575
		$prefix = "notification:method:";
576
		$return = new \stdClass;
577
578
		foreach ($all_metadata as $meta) {
579
			$name = substr($meta->name, strlen($prefix));
580
			$value = $meta->value;
581
582
			if (strpos($meta->name, $prefix) === 0) {
583
				$return->$name = $value;
584
			}
585
		}
586
587
		return $return;
588
	}
589
590
	return false;
591
}
592
593
/**
594
 * Set a user notification pref.
595
 *
596
 * @param int    $user_guid The user id.
597
 * @param string $method    The delivery method (eg. email)
598
 * @param bool   $value     On(true) or off(false).
599
 *
600
 * @return bool
601
 */
602
function set_user_notification_setting($user_guid, $method, $value) {
603
	$user_guid = (int)$user_guid;
604
	$method = sanitise_string($method);
605
606
	$user = get_entity($user_guid);
607
	if (!$user) {
608
		$user = elgg_get_logged_in_user_entity();
609
	}
610
611
	if (($user) && ($user instanceof \ElggUser)) {
612
		$prefix = "notification:method:$method";
613
		$user->$prefix = $value;
614
		$user->save();
615
616
		return true;
617
	}
618
619
	return false;
620
}
621
622
/**
623
 * Send an email to any email address
624
 *
625
 * @param string $from    Email address or string: "name <email>"
626
 * @param string $to      Email address or string: "name <email>"
627
 * @param string $subject The subject of the message
628
 * @param string $body    The message body
629
 * @param array  $params  Optional parameters (none used in this function)
630
 *
631
 * @return bool
632
 * @throws NotificationException
633
 * @since 1.7.2
634
 */
635
function elgg_send_email($from, $to, $subject, $body, array $params = null) {
636
	global $CONFIG;
637
638
	if (!$from) {
639
		$msg = "Missing a required parameter, '" . 'from' . "'";
640
		throw new \NotificationException($msg);
641
	}
642
643
	if (!$to) {
644
		$msg = "Missing a required parameter, '" . 'to' . "'";
645
		throw new \NotificationException($msg);
646
	}
647
648
	$headers = array(
649
		"Content-Type" => "text/plain; charset=UTF-8; format=flowed",
650
		"MIME-Version" => "1.0",
651
		"Content-Transfer-Encoding" => "8bit",
652
	);
653
654
	// return true/false to stop elgg_send_email() from sending
655
	$mail_params = array(
656
		'to' => $to,
657
		'from' => $from,
658
		'subject' => $subject,
659
		'body' => $body,
660
		'headers' => $headers,
661
		'params' => $params,
662
	);
663
664
	// $mail_params is passed as both params and return value. The former is for backwards
665
	// compatibility. The latter is so handlers can now alter the contents/headers of
666
	// the email by returning the array
667
	$result = elgg_trigger_plugin_hook('email', 'system', $mail_params, $mail_params);
668
	if (is_array($result)) {
669
		foreach (array('to', 'from', 'subject', 'body', 'headers') as $key) {
670
			if (isset($result[$key])) {
671
				${$key} = $result[$key];
672
			}
673
		}
674
	} elseif ($result !== null) {
675
		return $result;
676
	}
677
678
	$header_eol = "\r\n";
679
	if (isset($CONFIG->broken_mta) && $CONFIG->broken_mta) {
680
		// Allow non-RFC 2822 mail headers to support some broken MTAs
681
		$header_eol = "\n";
682
	}
683
684
	// Windows is somewhat broken, so we use just address for to and from
685
	if (strtolower(substr(PHP_OS, 0, 3)) == 'win') {
686
		// strip name from to and from
687
		if (strpos($to, '<')) {
688
			preg_match('/<(.*)>/', $to, $matches);
689
			$to = $matches[1];
690
		}
691
		if (strpos($from, '<')) {
692
			preg_match('/<(.*)>/', $from, $matches);
693
			$from = $matches[1];
694
		}
695
	}
696
697
	// make sure From is set
698
	if (empty($headers['From'])) {
699
		$headers['From'] = $from;
700
	}
701
702
	// stringify headers
703
	$headers_string = '';
704
	foreach ($headers as $key => $value) {
705
		$headers_string .= "$key: $value{$header_eol}";
706
	}
707
708
	// Sanitise subject by stripping line endings
709
	$subject = preg_replace("/(\r\n|\r|\n)/", " ", $subject);
710
	// this is because Elgg encodes everything and matches what is done with body
711
	$subject = html_entity_decode($subject, ENT_QUOTES, 'UTF-8'); // Decode any html entities
712
	if (is_callable('mb_encode_mimeheader')) {
713
		$subject = mb_encode_mimeheader($subject, "UTF-8", "B");
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $subject is correct as mb_encode_mimeheader($subject, 'UTF-8', 'B') (which targets mb_encode_mimeheader()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
714
	}
715
716
	// Format message
717
	$body = html_entity_decode($body, ENT_QUOTES, 'UTF-8'); // Decode any html entities
718
	$body = elgg_strip_tags($body); // Strip tags from message
719
	$body = preg_replace("/(\r\n|\r)/", "\n", $body); // Convert to unix line endings in body
720
	$body = preg_replace("/^From/", ">From", $body); // Change lines starting with From to >From
721
	$body = wordwrap($body);
722
723
	return mail($to, $subject, $body, $headers_string);
724
}
725
726
/**
727
 * Save personal notification settings - input comes from request
728
 *
729
 * @return void
730
 * @access private
731
 */
732
function _elgg_save_notification_user_settings() {
733
	$method = get_input('method');
734
735
	$current_settings = get_user_notification_settings();
736
737
	$result = false;
738
	foreach ($method as $k => $v) {
739
		// check if setting has changed and skip if not
740
		if ($current_settings->$k == ($v == 'yes')) {
741
			continue;
742
		}
743
744
		$result = set_user_notification_setting(elgg_get_logged_in_user_guid(), $k, ($v == 'yes') ? true : false);
745
746
		if (!$result) {
747
			register_error(elgg_echo('notifications:usersettings:save:fail'));
748
		}
749
	}
750
751
	if ($result) {
752
		system_message(elgg_echo('notifications:usersettings:save:ok'));
753
	}
754
}
755
756
/**
757
 * @access private
758
 */
759
function _elgg_notifications_test($hook, $type, $tests) {
760
	global $CONFIG;
761
	$tests[] = "{$CONFIG->path}engine/tests/ElggCoreDatabaseQueueTest.php";
762
	return $tests;
763
}
764
765
return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
766
	$events->registerHandler('init', 'system', '_elgg_notifications_init');
767
768
	$hooks->registerHandler('unit_test', 'system', '_elgg_notifications_test');
769
};
770