Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

mod/notifications/start.php (1 issue)

1
<?php
2
/**
3
 * Elgg notifications plugin
4
 *
5
 * @package ElggNotifications
6
 */
7
8
/**
9
 * Notifications init
10
 *
11
 * @return void
12
 */
13
function notifications_plugin_init() {
14
15 31
	elgg_extend_view('elgg.css', 'notifications.css');
16
17 31
	elgg_register_page_handler('notifications', 'notifications_page_handler');
18
19 31
	elgg_register_plugin_hook_handler('register', 'menu:title', '_notification_groups_title_menu');
20
21 31
	elgg_register_plugin_hook_handler('register', 'menu:page', '_notifications_page_menu');
22
23
	// Unset the default notification settings
24 31
	elgg_unregister_plugin_hook_handler('usersettings:save', 'user', '_elgg_save_notification_user_settings');
25 31
	elgg_unextend_view('forms/account/settings', 'core/settings/account/notifications');
26
27
	// update notifications based on relationships changing
28 31
	elgg_register_event_handler('delete', 'relationship', 'notifications_relationship_remove');
29
30
	// update notifications when new friend or access collection membership
31 31
	elgg_register_event_handler('create', 'relationship', 'notifications_update_friend_notify');
32 31
	elgg_register_plugin_hook_handler('access:collections:add_user', 'collection', 'notifications_update_collection_notify');
33
34
	// register unit tests
35 31
	elgg_register_plugin_hook_handler('unit_test', 'system', 'notifications_register_tests');
36 31
}
37
38
/**
39
 * Route page requests
40
 *
41
 * @param array $page Array of url parameters
42
 * @return bool
43
 */
44
function notifications_page_handler($page) {
45
46
	elgg_gatekeeper();
47
48
	// Set the context to settings
49
	elgg_set_context('settings');
50
51
	$current_user = elgg_get_logged_in_user_entity();
52
53
	// default to personal notifications
54
	if (!isset($page[0])) {
55
		$page[0] = 'personal';
56
	}
57
	if (!isset($page[1])) {
58
		forward("notifications/{$page[0]}/{$current_user->username}");
59
	}
60
61
	$vars['username'] = $page[1];
0 ignored issues
show
Comprehensibility Best Practice introduced by Steve Clay
$vars was never initialized. Although not strictly required by PHP, it is generally a good practice to add $vars = array(); before regardless.
Loading history...
62
63
	// note: $user passed in
64
	switch ($page[0]) {
65
		case 'group':
66
			echo elgg_view_resource('notifications/groups', $vars);
67
			break;
68
		case 'personal':
69
			echo elgg_view_resource('notifications/index', $vars);
70
			break;
71
		default:
72
			return false;
73
	}
74
	return true;
75
}
76
77
/**
78
 * Register menu items for the page menu
79
 *
80
 * @param string         $hook   'register'
81
 * @param string         $type   'menu:page'
82
 * @param ElggMenuItem[] $return current return value
83
 * @param array          $params supplied params
84
 *
85
 * @return void|ElggMenuItem[]
86
 *
87
 * @access private
88
 * @since 3.0
89
 */
90
function _notifications_page_menu($hook, $type, $return, $params) {
91
	
92 1
	if (!elgg_in_context('settings') || !elgg_get_logged_in_user_guid()) {
93 1
		return;
94
	}
95
96
	$user = elgg_get_page_owner_entity();
97
	if (!$user) {
98
		$user = elgg_get_logged_in_user_entity();
99
	}
100
	
101
	$return[] = \ElggMenuItem::factory([
102
		'name' => '2_a_user_notify',
103
		'text' => elgg_echo('notifications:subscriptions:changesettings'),
104
		'href' => "notifications/personal/{$user->username}",
105
		'section' => 'notifications',
106
	]);
107
	
108
	if (elgg_is_active_plugin('groups')) {
109
		$return[] = \ElggMenuItem::factory([
110
			'name' => '2_group_notify',
111
			'text' => elgg_echo('notifications:subscriptions:changesettings:groups'),
112
			'href' => "notifications/group/{$user->username}",
113
			'section' => 'notifications',
114
		]);
115
	}
116
		
117
	return $return;
118
}
119
120
/**
121
 * Register menu items for the title menu on group profiles
122
 *
123
 * @param \Elgg\Hook $hook 'register' 'menu:title'
124
 *
125
 * @return void
126
 *
127
 * @access private
128
 * @since 3.0
129
 */
130
function _notification_groups_title_menu(\Elgg\Hook $hook) {
131 1
	if (!elgg_is_active_plugin('groups')) {
132 1
		return;
133
	}
134
135
	$user = elgg_get_logged_in_user_entity();
136
	if (!$user) {
137
		return;
138
	}
139
140
	$items = $hook->getValue();
141
	
142
	$group = $hook->getEntityParam();
143
	if (!($group instanceof \ElggGroup)) {
144
		return;
145
	}
146
	
147
	$subscribed = false;
148
	$methods = elgg_get_notification_methods();
149
	foreach ($methods as $method) {
150
		$subscribed = check_entity_relationship($user->guid, 'notify' . $method, $group->guid);
151
		if ($subscribed) {
152
			break;
153
		}
154
	}
155
		
156
	$items[] = \ElggMenuItem::factory([
157
		'name' => 'notifications',
158
		'parent_name' => 'group-dropdown',
159
		'text' => elgg_echo('notifications:subscriptions:changesettings:groups'),
160
		'href' => "notifications/group/{$user->username}",
161
		'badge' => $subscribed ? elgg_echo('on') : elgg_echo('off'),
162
		'icon' => $subscribed ? 'bell' : 'bell-slash',
163
	]);
164
	
165
	return $items;
166
}
167
168
/**
169
 * Update notifications when a relationship is deleted
170
 *
171
 * @param string            $event        "delete"
172
 * @param string            $object_type  "relationship"
173
 * @param \ElggRelationship $relationship Relationship obj
174
 *
175
 * @return void
176
 */
177
function notifications_relationship_remove($event, $object_type, $relationship) {
178
	
179 6
	if (!$relationship instanceof ElggRelationship) {
180
		return;
181
	}
182
	
183 6
	if (!in_array($relationship->relationship, ['member', 'friend'])) {
184 4
		return;
185
	}
186
	
187 2
	$methods = array_keys(_elgg_services()->notifications->getMethodsAsDeprecatedGlobal());
188 2
	foreach ($methods as $method) {
189 2
		elgg_remove_subscription($relationship->guid_one, $method, $relationship->guid_two);
190
	}
191 2
}
192
193
/**
194
 * Turn on notifications for new friends if all friend notifications is on
195
 *
196
 * @param string           $event        'create'
197
 * @param string           $type         'relationship'
198
 * @param ElggRelationship $relationship new relationship
199
 *
200
 * @return void
201
 */
202
function notifications_update_friend_notify($event, $type, $relationship) {
203
	
204 24
	if (!$relationship instanceof ElggRelationship) {
205
		return;
206
	}
207
	
208
	// The handler gets triggered regardless of which relationship was
209
	// created, so proceed only if dealing with a 'friend' relationship.
210 24
	if ($relationship->relationship != 'friend') {
211 24
		return;
212
	}
213
214
	$NOTIFICATION_HANDLERS = _elgg_services()->notifications->getMethodsAsDeprecatedGlobal();
215
216
	$user_guid = $relationship->guid_one;
217
	$friend_guid = $relationship->guid_two;
218
219
	$user = get_entity($user_guid);
220
221
	// loop through all notification types
222
	foreach ($NOTIFICATION_HANDLERS as $method => $foo) {
223
		$metaname = 'collections_notifications_preferences_' . $method;
224
		$collections_preferences = $user->$metaname;
225
		if ($collections_preferences) {
226
			if (!empty($collections_preferences) && !is_array($collections_preferences)) {
227
				$collections_preferences = [$collections_preferences];
228
			}
229
			if (is_array($collections_preferences)) {
230
				// -1 means all friends is on - should be a define
231
				if (in_array(-1, $collections_preferences)) {
232
					add_entity_relationship($user_guid, 'notify' . $method, $friend_guid);
233
				}
234
			}
235
		}
236
	}
237
}
238
239
/**
240
 * Update notifications for changes in access collection membership.
241
 *
242
 * This function assumes that only friends can belong to access collections.
243
 *
244
 * @param string $event       'access:collections:add_user'
245
 * @param string $type        'collection'
246
 * @param bool   $returnvalue current return value
247
 * @param array  $params      supplied params
248
 *
249
 * @return void
250
 */
251
function notifications_update_collection_notify($event, $type, $returnvalue, $params) {
252 14
	$NOTIFICATION_HANDLERS = _elgg_services()->notifications->getMethodsAsDeprecatedGlobal();
253
254
	// only update notifications for user owned collections
255 14
	$collection_id = elgg_extract('collection_id', $params);
256 14
	$collection = get_access_collection($collection_id);
257 14
	if (!$collection instanceof ElggAccessCollection) {
258
		return;
259
	}
260 14
	$user = get_entity($collection->owner_guid);
261 14
	if (!($user instanceof ElggUser)) {
262 8
		return;
263
	}
264
265 6
	$member_guid = (int) elgg_extract('user_guid', $params);
266 6
	if (empty($member_guid)) {
267
		return;
268
	}
269
270
	// loop through all notification types
271 6
	foreach ($NOTIFICATION_HANDLERS as $method => $foo) {
272 6
		$metaname = 'collections_notifications_preferences_' . $method;
273 6
		$collections_preferences = $user->$metaname;
274 6
		if (!$collections_preferences) {
275 6
			continue;
276
		}
277
		if (!is_array($collections_preferences)) {
278
			$collections_preferences = [$collections_preferences];
279
		}
280
		if (in_array(-1, $collections_preferences)) {
281
			// if "all friends" notify is on, we don't change any notifications
282
			// since must be a friend to be in an access collection
283
			continue;
284
		}
285
		if (in_array($collection_id, $collections_preferences)) {
286
			// notifications are on for this collection so we add/remove
287
			if ($event == 'access:collections:add_user') {
288
				add_entity_relationship($user->guid, "notify$method", $member_guid);
289
			} elseif ($event == 'access:collections:remove_user') {
290
				// removing someone from an access collection is not a guarantee
291
				// that they should be removed from notifications
292
				//remove_entity_relationship($user->guid, "notify$method", $member_guid);
293
			}
294
		}
295
	}
296 6
}
297
298
/**
299
 * Register unit tests
300
 *
301
 * @param string   $hook  "unit_test"
302
 * @param string   $type  "system"
303
 * @param string[] $tests Tests
304
 *
305
 * @return string[]
306
 */
307
function notifications_register_tests($hook, $type, $tests) {
308
	$tests[] = __DIR__ . '/tests/ElggNotificationsPluginUnitTest.php';
309
	return $tests;
310
}
311
312
return function() {
313 18
	elgg_register_event_handler('init', 'system', 'notifications_plugin_init');
314
};
315