We are moving to Git Issues for bug tracking in future releases. During transition, content will be in both tools. If you'd like to file a new bug, please create an issue.

View | Details | Raw Unified | Return to bug 3922 | Differences between
and this patch

Collapse All | Expand All

(-)classes/core/PKPApplication.inc.php (+2 lines)
 Lines 186-191    Link Here 
186
			'CurrencyDAO' => 'currency.CurrencyDAO',
186
			'CurrencyDAO' => 'currency.CurrencyDAO',
187
			'HelpTocDAO' => 'help.HelpTocDAO',
187
			'HelpTocDAO' => 'help.HelpTocDAO',
188
			'HelpTopicDAO' => 'help.HelpTopicDAO',
188
			'HelpTopicDAO' => 'help.HelpTopicDAO',
189
			'NotificationDAO' => 'notification.NotificationDAO',
190
			'NotificationSettingsDAO' => 'notification.NotificationSettingsDAO',
189
			'ScheduledTaskDAO' => 'scheduledTask.ScheduledTaskDAO',
191
			'ScheduledTaskDAO' => 'scheduledTask.ScheduledTaskDAO',
190
			'SessionDAO' => 'session.SessionDAO',
192
			'SessionDAO' => 'session.SessionDAO',
191
			'SiteDAO' => 'site.SiteDAO',
193
			'SiteDAO' => 'site.SiteDAO',
(-)classes/notification/NotificationDAO.inc.php (+325 lines)
Added Link Here 
1
<?php
2
3
/**
4
 * @file classes/notification/NotificationDAO.inc.php
5
 *
6
 * Copyright (c) 2003-2008 John Willinsky
7
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
8
 *
9
 * @class NotificationDAO
10
 * @ingroup notification
11
 * @see Notification
12
 *
13
 * @brief Operations for retrieving and modifying Notification objects.
14
 */
15
16
// $Id: NotificationDAO.inc.php,v 1.19 2008/11/05 00:46:39 mcrider Exp $
17
18
import('notification.Notification');
19
20
class NotificationDAO extends DAO {
21
	/**
22
	 * Constructor.
23
	 */
24
	function NotificationDAO() {
25
		parent::DAO();
26
	}
27
	
28
	/**
29
	 * Retrieve Notification by notification id
30
	 * @param $notificationId int
31
	 * @return Notification object
32
	 */
33
	function &getNotificationById($notificationId) {
34
		$result =& $this->retrieve(
35
			'SELECT * FROM notifications WHERE notification_id = ?', (int) $notificationId
36
		);
37
	
38
		$notification =& $this->_returnNotificationFromRow($result->GetRowAssoc(false));
39
	
40
		$result->Close();
41
		unset($result);
42
	
43
		return $notification;
44
	}	
45
	
46
	/**
47
	 * Retrieve Notifications by user id
48
	 * @param $userId int
49
	 * @return Notification objects array
50
	 */
51
	function &getNotificationsByUserId($userId) {
52
		$application =& PKPApplication::getApplication();
53
		$productName = $application->getName();
54
		$context =& Request::getContext();
55
		$contextId = $context->getId();
56
		
57
		$notifications = array();
58
	
59
		$result =& $this->retrieve(
60
			'SELECT * FROM notifications WHERE user_id = ? AND product = ? AND context = ? ORDER BY date_created DESC',	
61
			array((int) $userId, $productName, (int) $contextId)
62
		);
63
	
64
		$returner = new DAOResultFactory($result, $this, '_returnNotificationFromRow');
65
		
66
		return $returner;
67
	}
68
	
69
	/**
70
	 * Retrieve Notifications by notification id
71
	 * @param $notificationId int
72
	 * @return boolean
73
	 */
74
	function setDateRead($notificationId) {
75
		$returner = $this->update(
76
			sprintf('UPDATE notifications
77
				SET date_read = %s
78
				WHERE notification_id = ?',
79
				$this->datetimeToDB(date('Y-m-d H:i:s'))),
80
			(int) $notificationId
81
		);
82
83
		return $returner;
84
	}
85
	
86
	/**
87
	 * Creates and returns an notification object from a row
88
	 * @param $row array
89
	 * @return Notification object
90
	 */
91
	function &_returnNotificationFromRow($row) {
92
		$notification = new Notification();
93
		$notification->setNotificationId($row['notification_id']);
94
		$notification->setUserId($row['user_id']);
95
		$notification->setDateCreated($row['date_created']);
96
		$notification->setDateRead($row['date_read']);
97
		$notification->setContents($row['contents']);
98
		$notification->setParam($row['param']);
99
		$notification->setLocation($row['location']);
100
		$notification->setIsLocalized($row['is_localized']);
101
		$notification->setContext($row['context']);
102
		$notification->setAssocType($row['assoc_type']);
103
		
104
		HookRegistry::call('NotificationDAO::_returnNotificationFromRow', array(&$notification, &$row));
105
	
106
		return $notification;
107
	}
108
	
109
	/**
110
	 * Inserts a new notification into notifications table
111
	 * @param Notification object
112
	 * @return int Notification Id 
113
	 */
114
	function insertNotification(&$notification) {
115
		$application =& PKPApplication::getApplication();
116
		$productName = $application->getName();
117
		
118
		if ($this->notificationAlreadyExists($notification)) {
119
			return 0;
120
		}
121
		
122
		$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
123
		$notificationSettings = $notificationSettingsDao->getNotificationSettings($notification->getUserId());
124
		$notificationEmailSettings = $notificationSettingsDao->getNotificationEmailSettings($notification->getUserId());
125
		
126
		if(in_array($notification->getAssocType(), $notificationEmailSettings)) {
127
			$this->sendNotificationEmail($notification);
128
		}
129
		
130
		if(!in_array($notification->getAssocType(), $notificationSettings)) {
131
			$this->update(
132
				sprintf('INSERT INTO notifications
133
					(user_id, date_created, contents, param, location, is_localized, context, product, assoc_type)
134
					VALUES
135
					(?, %s, ?, ?, ?, ?, ?, ?, ?)',
136
					$this->datetimeToDB(date('Y-m-d H:i:s'))),
137
				array(
138
					(int) $notification->getUserId(),
139
					$notification->getContents(),
140
					$notification->getParam(),
141
					$notification->getLocation(),
142
					(int) $notification->getIsLocalized(),
143
					(int) $notification->getContext(),
144
					$productName,
145
					(int) $notification->getAssocType(),
146
				)
147
			);
148
		
149
			$notification->setNotificationId($this->getInsertNotificationId());
150
			return $notification->getNotificationId();
151
		} else return 0;
152
	}
153
	
154
	/**
155
	 * Delete Notification by notification id
156
	 * @param $notificationId int
157
	 * @return boolean
158
	 */
159
	function deleteNotificationById($notificationId, $userId = null) {
160
		$params = array($notificationId);
161
		if (isset($userId)) $params[] = $userId;
162
	
163
		return $this->update('DELETE FROM notifications WHERE notification_id = ?' . (isset($userId) ? ' AND user_id = ?' : ''), 
164
			$params
165
		);
166
	}	
167
168
	/**
169
	 * Check if the same notification was added in the last hour
170
	 * Will prevent multiple notifications to show up in a user's feed e.g.
171
	 * if a user edits a submission multiple times in a short time span
172
	 * @param notification object
173
	 * @return boolean
174
	 */
175
	function notificationAlreadyExists(&$notification) {
176
		$application =& PKPApplication::getApplication();
177
		$productName = $application->getName();
178
		$context =& Request::getContext();
179
		$contextId = $context->getId();
180
			
181
		$result =& $this->retrieve(
182
			'SELECT date_created FROM notifications WHERE user_id = ? AND contents = ? AND product = ? AND assoc_type = ? AND context = ?',
183
			array(
184
					(int) $notification->getUserId(),
185
					$notification->getContents(),
186
					$productName,
187
					(int) $notification->getAssocType(),
188
					(int) $contextId
189
				)
190
		);
191
		
192
		$date = isset($result->fields[0]) ? $result->fields[0] : 0;
193
		
194
		if ($date == 0) {
195
			return false;
196
		} else {
197
			$timeDiff = strtotime($date) - time();
198
			if ($timeDiff < 3600) { // 1 hour (in seconds)
199
				return true;
200
			} else return false;
201
		}
202
	}
203
204
	/**
205
	 * Get the ID of the last inserted notification
206
	 * @return int
207
	 */
208
	function getInsertNotificationId() {
209
		return $this->getInsertId('notifications', 'notification_id');
210
	}
211
	
212
	/**
213
	 * Get the number of unread messages for a user
214
	 * @param $userId int
215
	 * @return int
216
	 */
217
	function getUnreadNotificationCount($userId) {
218
		$application =& PKPApplication::getApplication();
219
		$productName = $application->getName();
220
		$context =& Request::getContext();
221
		$contextId = $context->getId();
222
		
223
		$result =& $this->retrieve(
224
			'SELECT count(*) FROM notifications WHERE user_id = ? AND date_read IS NULL AND product = ? AND context = ?',
225
			array((int) $userId, $productName, (int) $contextId)
226
		);
227
228
		$returner = $result->fields[0];
229
230
		$result->Close();
231
		unset($result);
232
233
		return $returner;
234
	}
235
	
236
	/**
237
	 * Get the number of read messages for a user
238
	 * @param $userId int
239
	 * @return int
240
	 */
241
	function getReadNotificationCount($userId) {
242
		$application =& PKPApplication::getApplication();
243
		$productName = $application->getName();
244
		$context =& Request::getContext();
245
		$contextId = $context->getId();
246
		
247
		$result =& $this->retrieve(
248
			'SELECT count(*) FROM notifications WHERE user_id = ? AND date_read IS NOT NULL AND product = ? AND context = ?',
249
			array((int) $userId, $productName, (int) $contextId)
250
		);
251
252
		$returner = $result->fields[0];
253
254
		$result->Close();
255
		unset($result);
256
257
		return $returner;
258
	}
259
260
	/**
261
	 * Send an email to a user regarding the notification
262
	 * @param $notification object Notification
263
	 */
264
	function sendNotificationEmail($notification) {
265
		$userId = $notification->getUserId();
266
		$userDao =& DAORegistry::getDAO('UserDAO');
267
		$user = $userDao->getUser($userId);
268
		
269
		if ($notification->getIsLocalized()) {
270
			$params = array('param' => $notification->getParam());
271
			$notificationContents = Locale::translate($notification->getContents(), $params);
272
		} else {
273
			$notificationContents = $notification->getContents();
274
		}
275
		
276
		import('mail.MailTemplate');
277
		$site =& Request::getSite();
278
		$mail = new MailTemplate('NOTIFICATION');
279
		$mail->setFrom($site->getSiteContactEmail(), $site->getSiteContactName());
280
		$mail->assignParams(array(
281
			'notificationContents' => $notificationContents,
282
			'url' => $notification->getLocation(),
283
			'siteTitle' => $site->getSiteTitle()
284
		));
285
		$mail->addRecipient($user->getEmail(), $user->getFullName());
286
		$mail->send();
287
	}	
288
	
289
	/**
290
	 * Send an update to all users on the mailing list
291
	 * @param $notification object Notification
292
	 */
293
	function sendToMailingList($notification) {
294
		$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
295
		$mailList = $notificationSettingsDao->getMailList();
296
		
297
		foreach ($mailList as $email) {
298
			if ($notification->getIsLocalized()) {
299
				$params = array('param' => $notification->getParam());
300
				$notificationContents = Locale::translate($notification->getContents(), $params);
301
			} else {
302
				$notificationContents = $notification->getContents();
303
			}
304
			
305
			import('mail.MailTemplate');
306
			$journal =& Request::getJournal();
307
			$site =& Request::getSite();
308
			
309
			$mail = new MailTemplate('NOTIFICATION_MAILLIST');
310
			$mail->setFrom($site->getSiteContactEmail(), $site->getSiteContactName());
311
			$mail->assignParams(array(
312
				'notificationContents' => $notificationContents,
313
				'url' => $notification->getLocation(),
314
				'siteTitle' => $journal->getJournalTitle(),
315
				'unsubscribeLink' => Request::url(null, 'notification', 'unsubscribeMailList')
316
			));
317
			$mail->addRecipient($email);
318
			$mail->send();
319
		}
320
		
321
		
322
	}	
323
}
324
325
?>
(-)classes/notification/NotificationSettingsDAO.inc.php (+453 lines)
Added Link Here 
1
<?php
2
3
/**
4
 * @file classes/notification/NotificationSettingsDAODAO.inc.php
5
 *
6
 * Copyright (c) 2003-2008 John Willinsky
7
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
8
 *
9
 * @class NotificationSettingsDAO
10
 * @ingroup notification
11
 * @see Notification
12
 *
13
 * @brief Operations for retrieving and modifying user's notification settings.
14
 */
15
16
// $Id: NotificationSettingsDAO.inc.php,v 1.19 2008/11/05 00:46:39 mcrider Exp $
17
18
class NotificationSettingsDAO extends DAO {
19
	/**
20
	 * Constructor.
21
	 */
22
	function NotificationSettingsDAO() {
23
		parent::DAO();
24
	}
25
	
26
	/**
27
	 * Retrieve Notifications settings by user id
28
	 * Returns an array of notification types that the user
29
	 * does NOT want to be notified of
30
	 * @param $userId int
31
	 * @return array
32
	 */
33
	function &getNotificationSettings($userId) {
34
		$application =& PKPApplication::getApplication();
35
		$productName = $application->getName();
36
		$context =& Request::getContext();
37
		$contextId = $context->getId();
38
		
39
		$notificationSettings = array();
40
	
41
		$result =& $this->retrieve(
42
			'SELECT setting_value FROM notification_settings WHERE user_id = ? AND product = ? AND setting_name = ? AND context = ?',
43
				array((int) $userId, $productName, 'notify', (int) $contextId)
44
		);
45
	
46
		while (!$result->EOF) {
47
			$row = $result->GetRowAssoc(false);
48
			$notificationSettings[] = (int) $row['setting_value'];
49
			$result->moveNext();
50
		}
51
52
		$result->Close();
53
		unset($result);
54
		
55
		return $notificationSettings;
56
	}
57
	
58
	/**
59
	 * Retrieve Notifications email settings by user id
60
	 * Returns an array of notification types that the user
61
	 * DOES want to be emailed about
62
	 * @param $userId int
63
	 * @return array
64
	 */
65
	function &getNotificationEmailSettings($userId) {
66
		$application =& PKPApplication::getApplication();
67
		$productName = $application->getName();
68
		$context =& Request::getContext();
69
		$contextId = $context->getId();
70
		
71
		$emailSettings = array();
72
	
73
		$result =& $this->retrieve(
74
			'SELECT setting_value FROM notification_settings WHERE user_id = ? AND product = ? AND setting_name = ? AND context = ?',
75
				array((int) $userId, $productName, 'email', (int) $contextId)
76
		);
77
	
78
		while (!$result->EOF) {
79
			$row = $result->GetRowAssoc(false);
80
			$emailSettings[] = (int) $row['setting_value'];
81
			$result->moveNext();
82
		}
83
84
		$result->Close();
85
		unset($result);
86
		
87
		return $emailSettings;
88
	}
89
	
90
	/**
91
	 * Update a user's notification settings
92
	 * @param $notificationSettings array
93
	 * @param $userId int
94
	 */
95
	function updateNotificationSettings($notificationSettings, $userId) {
96
		$application =& PKPApplication::getApplication();
97
		$productName = $application->getName();
98
		$context =& Request::getContext();
99
		$contextId = $context->getId();		
100
		
101
		// Delete old settings first, then insert new settings
102
		$this->update('DELETE FROM notification_settings WHERE user_id = ? AND product = ? AND setting_name = ? AND context = ?',
103
			array((int) $userId, $productName, 'notify', (int) $contextId));
104
	
105
		for ($i=0; $i<count($notificationSettings); $i++) {
106
			$this->update(
107
				'INSERT INTO notification_settings
108
					(setting_name, setting_value, user_id, product, context)
109
					VALUES
110
					(?, ?, ?, ?, ?)',
111
				array(
112
					"notify",
113
					$notificationSettings[$i],
114
					(int) $userId,
115
					$productName,
116
					(int) $contextId
117
				)
118
			);
119
		}
120
	}
121
	
122
	/**
123
	 * Update a user's notification email settings
124
	 * @param $notificationEmailSettings array
125
	 * @param $userId int
126
	 */
127
	function updateNotificationEmailSettings($emailSettings, $userId) {
128
		$application =& PKPApplication::getApplication();
129
		$productName = $application->getName();
130
		$context =& Request::getContext();
131
		$contextId = $context->getId();
132
		
133
		// Delete old settings first, then insert new settings
134
		$this->update('DELETE FROM notification_settings WHERE user_id = ? AND product = ? AND setting_name = ? AND context = ?',
135
			array($userId, $productName, 'email', $contextId));
136
	
137
		for ($i=0; $i<count($emailSettings); $i++) {
138
			$this->update(
139
				'INSERT INTO notification_settings
140
					(setting_name, setting_value, user_id, product, context)
141
					VALUES
142
					(?, ?, ?, ?, ?)',
143
				array(
144
					"email",
145
					$emailSettings[$i],
146
					(int) $userId,
147
					$productName,
148
					(int) $contextId
149
				)
150
			);
151
		}
152
	}
153
	
154
	/**
155
	 * Gets a user id by an RSS token value
156
	 * @param $token int
157
	 * @return int
158
	 */
159
	function getUserIdByRSSToken($token) {
160
		$application =& PKPApplication::getApplication();
161
		$productName = $application->getName();
162
		$context =& Request::getContext();
163
		$contextId = $context->getId();
164
	
165
		$result =& $this->retrieve(
166
			'SELECT user_id FROM notification_settings WHERE setting_value = ? AND setting_name = ? AND product = ? AND context = ?',
167
				array($token, 'token', $productName, (int) $contextId)
168
		);
169
170
		$row = $result->GetRowAssoc(false);
171
		$userId = $row['user_id'];
172
173
		$result->Close();
174
		unset($result);
175
		
176
		return $userId;
177
	}
178
179
	/**
180
	 * Gets an RSS token for a user id
181
	 * @param $userId int
182
	 * @return int
183
	 */
184
	function getRSSTokenByUserId($userId) {
185
		$application =& PKPApplication::getApplication();
186
		$productName = $application->getName();
187
		$context =& Request::getContext();
188
		$contextId = $context->getId();
189
	
190
		$result =& $this->retrieve(
191
			'SELECT setting_value FROM notification_settings WHERE user_id = ? AND setting_name = ? AND product = ? AND context = ?',
192
				array((int) $userId, 'token', $productName, (int) $contextId)
193
		);
194
195
		$row = $result->GetRowAssoc(false);
196
		$userId = $row['setting_value'];
197
198
		$result->Close();
199
		unset($result);
200
		
201
		return $userId;
202
	}
203
204
	/**
205
	 * Generates and inserts a new token for a user's RSS feed
206
	 * @param $userId int
207
	 * @return int
208
	 */
209
	function insertNewRSSToken($userId) {
210
		$application =& PKPApplication::getApplication();
211
		$productName = $application->getName();
212
		$context =& Request::getContext();
213
		$contextId = $context->getId();
214
		
215
		$token = uniqid(rand());
216
	
217
		$this->update(
218
			'INSERT INTO notification_settings
219
				(setting_name, setting_value, user_id, product, context)
220
				VALUES
221
				(?, ?, ?, ?, ?)',
222
			array(
223
				'token',
224
				$token,
225
				(int) $userId,
226
				$productName,
227
				(int) $contextId
228
			)
229
		);
230
231
		return $token;
232
	}
233
	
234
	/**
235
	 * Generates an access key for the guest user and adds them to the settings table
236
	 * @param $userId int
237
	 * @return int
238
	 */
239
	function subscribeGuest($email) {
240
		$application =& PKPApplication::getApplication();
241
		$productName = $application->getName();
242
		$context =& Request::getContext();
243
		$contextId = $context->getId();
244
245
		// Check that the email doesn't already exist
246
		$result =& $this->retrieve(
247
			'SELECT * FROM notification_settings WHERE setting_name = ? AND setting_value = ? AND product = ? AND context = ?',
248
			array(
249
				'mailList',
250
				$email,
251
				$productName,
252
				(int) $contextId
253
			)
254
		);
255
256
		if ($result->RecordCount() != 0) {
257
			return false;
258
		} else {		
259
			$this->update(
260
				'INSERT INTO notification_settings
261
					(setting_name, setting_value, user_id, product, context)
262
					VALUES
263
					(?, ?, ?, ?, ?)',
264
				array(
265
					'mailListUncomfirmed',
266
					$email,
267
					0,
268
					$productName,
269
					(int) $contextId
270
				)
271
			);
272
		}	
273
274
		// Get assoc_id into notification_settings table, also used as user_id for access key
275
		$assocId = $this->getInsertNotificationSettingId();
276
277
		import('security.AccessKeyManager');
278
		$accessKeyManager = new AccessKeyManager();
279
280
		$password = $accessKeyManager->createKey('MailListContext', $assocId, $assocId, 10000);
281
		return $password;
282
	}
283
	
284
	
285
	
286
	/**
287
	 * Removes an email address and associated access key from email notifications
288
	 * @param $email string
289
	 * @param $password string
290
	 * @return boolean
291
	 */
292
	function unsubscribeGuest($email, $password) {
293
		$application =& PKPApplication::getApplication();
294
		$productName = $application->getName();
295
		$context =& Request::getContext();
296
		$contextId = $context->getId();
297
		
298
		$result =& $this->retrieve(
299
			'SELECT setting_id FROM notification_settings WHERE setting_name = ? AND product = ? AND context = ?',
300
			array(
301
				'mailList',
302
				$productName,
303
				(int) $contextId
304
			)
305
		);
306
307
		$row = $result->GetRowAssoc(false);
308
		$userId = (int) $row['setting_id'];
309
310
		$result->Close();
311
		unset($result);
312
313
		import('security.AccessKeyManager');
314
		$accessKeyManager = new AccessKeyManager();
315
		$accessKeyHash = AccessKeyManager::generateKeyHash($password);
316
		$accessKey = $accessKeyManager->validateKey('MailListContext', $userId, $accessKeyHash);
317
318
		if ($accessKey) {
319
			$this->update(
320
				'DELETE FROM notification_settings WHERE setting_name = ? AND setting_value = ? AND product = ? AND context = ?',
321
				array(
322
					'mailList',
323
					$email,
324
					$productName,
325
					(int) $contextId
326
				)
327
			);
328
			$accessKeyDao =& DAORegistry::getDAO('AccessKeyDAO');
329
			$accessKeyDao->deleteAccessKey($accessKey);
330
			return true;
331
		} else return false;	
332
	}
333
	
334
	/**
335
	 * Gets the setting id for a maillist member (to access the accompanying access key)
336
	 * @return array
337
	 */
338
	function getMailListSettingId($email, $settingName = 'mailListUncomfirmed') {
339
		$application =& PKPApplication::getApplication();
340
		$productName = $application->getName();
341
		$context =& Request::getContext();
342
		$contextId = $context->getId();	
343
		
344
		$result =& $this->retrieve(
345
			'SELECT setting_id FROM notification_settings WHERE setting_name = ? AND setting_value = ? AND product = ? AND context = ?',
346
			array(
347
				$settingName,
348
				$email,
349
				$productName,
350
				(int) $contextId
351
			)
352
		);
353
		
354
		$row = $result->GetRowAssoc(false);
355
		$settingId = (int) $row['setting_id'];
356
		
357
		return $settingId;
358
	}
359
	
360
	/**
361
	 * Update the notification settings table to confirm the mailing list subscription
362
	 * @return boolean
363
	 */
364
	function confirmMailListSubscription($settingId) {
365
		return $this->update(
366
			'UPDATE notification_settings SET setting_name = ? WHERE setting_id = ?',
367
			array('mailList', (int) $settingId)
368
		);
369
	}
370
371
	/**
372
	 * Gets a list of email addresses of users subscribed to the mailing list
373
	 * @return array
374
	 */
375
	function getMailList() {
376
		$application =& PKPApplication::getApplication();
377
		$productName = $application->getName();
378
		$context =& Request::getContext();
379
		$contextId = $context->getId();
380
		$mailList = array();
381
		
382
		$result =& $this->retrieve(
383
			'SELECT setting_value FROM notification_settings WHERE setting_name = ? AND product = ? AND context = ?',
384
			array(
385
				'mailList',
386
				$productName,
387
				(int) $contextId
388
			)
389
		);
390
391
		while (!$result->EOF) {
392
			$row = $result->GetRowAssoc(false);
393
			$mailList[] = $row['setting_value'];
394
			$result->moveNext();
395
		}
396
397
		$result->Close();
398
		unset($result);
399
		
400
		return $mailList;
401
	}
402
403
	/**
404
	 * Generates and inserts a new password for a mailing list user
405
	 * @param $email string
406
	 * @return string
407
	 */
408
	function resetPassword($email) {
409
		$application =& PKPApplication::getApplication();
410
		$productName = $application->getName();
411
		$context =& Request::getContext();
412
		$contextId = $context->getId();
413
		
414
		$result =& $this->retrieve(
415
			'SELECT setting_id FROM notification_settings WHERE setting_name = ? AND setting_value = ? AND product = ? AND context = ?',
416
			array(
417
				'mailList',
418
				$email,
419
				$productName,
420
				(int) $contextId
421
			)
422
		);
423
424
		$row = $result->GetRowAssoc(false);
425
		$settingId = $row['setting_id'];
426
427
		$result->Close();
428
		unset($result);
429
430
		$accessKeyDao =& DAORegistry::getDAO('AccessKeyDAO');
431
		$accessKey = $accessKeyDao->getAccessKeyByUserId('MailListContext', $settingId);
432
433
		if ($accessKey) {
434
			$key = Validation::generatePassword();
435
			$accessKey->setKeyHash(md5($key));
436
			
437
			$accessKeyDao =& DAORegistry::getDAO('AccessKeyDAO');
438
			$accessKeyDao->updateAccessKey($accessKey);
439
			return $key;
440
		} else return false;
441
	}
442
443
	/**
444
	 * Get the ID of the last inserted notification
445
	 * @return int
446
	 */
447
	function getInsertNotificationSettingId() {
448
		return $this->getInsertId('notification_settings', 'setting_id');
449
	}
450
451
}
452
453
?>
(-)classes/notification/PKPNotification.inc.php (+252 lines)
Added Link Here 
1
<?php
2
3
/**
4
 * @file classes/notification/Notification.inc.php
5
 *
6
 * Copyright (c) 2003-2008 John Willinsky
7
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
8
 *
9
 * @class Notification
10
 * @ingroup notification
11
 * @see NotificationDAO
12
 * @brief Class for Notification.
13
 */
14
15
// $Id: Notification.inc.php,v 1.10 2008/07/01 01:16:09 asmecher Exp $
16
17
import('notification.NotificationDAO');
18
19
class PKPNotification extends DataObject {
20
21
	/**
22
	 * Constructor.
23
	 */
24
	function PKPNotification() {
25
		parent::DataObject();
26
	}
27
	
28
	/**
29
	 * Create a new notification with the specified arguments and insert into DB
30
	 * This is a static method
31
	 * @param $userId int
32
	 * @param $contents string
33
	 * @param $param string
34
	 * @param $location string
35
	 * @param $isLocalized bool
36
	 * @param $assocType int
37
	 * @param $assocId int
38
	 * @return Notification object
39
	 */
40
	function createNotification($userId, $contents, $param, $location, $isLocalized, $assocType) {
41
		$notification = new Notification();
42
		$context =& Request::getContext();
43
		$contextId = $context->getId();
44
45
		$notification->setUserId($userId);
46
		$notification->setContents($contents);
47
		$notification->setParam($param);
48
		$notification->setLocation($location);
49
		$notification->setIsLocalized($isLocalized);
50
		$notification->setAssocType($assocType);
51
		$notification->setContext($contextId);
52
		
53
		$notificationDao =& DAORegistry::getDAO('NotificationDAO');
54
		$notificationDao->insertNotification($notification);
55
		
56
		return $notification;
57
	}
58
59
	/**
60
	 * get notification id
61
	 * @return int
62
	 */
63
	function getNotificationId() {
64
		return $this->getData('notificationId');
65
	}
66
67
	/**
68
	 * set notification id
69
	 * @param $commentId int
70
	 */
71
	function setNotificationId($notificationId) {
72
		return $this->setData('notificationId', $notificationId);
73
	}
74
	
75
	/**
76
	 * get user id associated with this notification
77
	 * @return int
78
	 */
79
	function getUserId() {
80
		return $this->getData('userId');
81
	}
82
	
83
	/**
84
	 * set user id associated with this notification
85
	 * @param $userId int
86
	 */
87
	function setUserId($userId) {
88
		return $this->setData('userId', $userId);
89
	}
90
	
91
	/**
92
	 * get date notification was created
93
	 * @return date (YYYY-MM-DD HH:MM:SS)
94
	 */
95
	function getDateCreated() {
96
		return $this->getData('dateCreated');
97
	}
98
	
99
	/**
100
	 * set date notification was created
101
	 * @param $dateCreated date (YYYY-MM-DD HH:MM:SS)
102
	 */
103
	function setDateCreated($dateCreated) {
104
		return $this->setData('dateCreated', $dateCreated);
105
	}
106
	
107
	/**
108
	 * get date notification is read by user
109
	 * @return date (YYYY-MM-DD HH:MM:SS)
110
	 */
111
	function getDateRead() {
112
		return $this->getData('dateRead');
113
	}
114
	
115
	/**
116
	 * set date notification is read by user
117
	 * Also sets setisUnread() if $dateRead is null
118
	 * @param $dateRead date (YYYY-MM-DD HH:MM:SS)
119
	 */
120
	function setDateRead($dateRead) {
121
		if(!isset($dateRead)) {
122
			$this->setIsUnread(true);
123
			$notificationDao =& DAORegistry::getDAO('NotificationDAO');
124
			$notificationDao->setDateRead($this->getNotificationId());
125
		} else {
126
			$this->setIsUnread(false);
127
			return $this->setData('dateRead', $dateRead);	
128
		}
129
	}
130
	
131
	/**
132
	 * return true if reading for the first time
133
	 * @return bool
134
	 */
135
	function getIsUnread() {
136
		return $this->getData('isUnread');
137
	}
138
	
139
	/**
140
	 * set to true if notification has not been read
141
	 * @param $isUnread bool
142
	 */
143
	function setIsUnread($isUnread) {
144
		return $this->setData('isUnread', $isUnread);
145
	}
146
	
147
	/**
148
	 * get notification contents
149
	 * @return string
150
	 */
151
	function getContents() {
152
		return $this->getData('contents');
153
	}
154
	
155
	/**
156
	 * set notification contents
157
	 * @param $contents int
158
	 */
159
	function setContents($contents) {
160
		return $this->setData('contents', $contents);
161
	}
162
	
163
	/**
164
	 * get optional parameter (e.g. article title)
165
	 * @return string
166
	 */
167
	function getParam() {
168
		return $this->getData('param');
169
	}
170
	
171
	/**
172
	 * set optional parameter
173
	 * @param $param int
174
	 */
175
	function setParam($param) {
176
		return $this->setData('param', $param);
177
	}
178
	
179
	/**
180
	 * get URL that notification refers to
181
	 * @return int
182
	 */
183
	function getLocation() {
184
		return $this->getData('location');
185
	}
186
	
187
	/**
188
	 * set URL that notification refers to
189
	 * @param $location int
190
	 */
191
	function setLocation($location) {
192
		return $this->setData('location', $location);
193
	}
194
	
195
	/**
196
	 * return true if message is localized (i.e. a system message)
197
	 * @return int
198
	 */
199
	function getIsLocalized() {
200
		return $this->getData('isLocalized');
201
	}
202
	
203
	/**
204
	 * set to true if message is localized (i.e. is a system message)
205
	 * @param $isLocalized int
206
	 */
207
	function setIsLocalized($isLocalized) {
208
		return $this->setData('isLocalized', $isLocalized);
209
	}
210
211
	/**
212
	 * get notification type
213
	 * @return int
214
	 */
215
	function getAssocType() {
216
		return $this->getData('assocType');
217
	}
218
219
	/**
220
	 * set notification type
221
	 * @param $assocType int
222
	 */
223
	function setAssocType($assocType) {
224
		return $this->setData('assocType', $assocType);
225
	}
226
	
227
	/**
228
	 * get context id
229
	 * @return int
230
	 */
231
	function getContext() {
232
		return $this->getData('context');
233
	}
234
	/**
235
	 * set context id
236
	 * @param $context int
237
	 */
238
	function setContext($context) {
239
		return $this->setData('context', $context);
240
	}	
241
	
242
	/**
243
	 * return the path to the icon for this type
244
	 * @return string
245
	 */
246
	function getIconLocation() {
247
		die ('ABSTRACT CLASS');
248
	}
249
250
 }
251
252
?>
(-)classes/notification/form/PKPNotificationSettingsForm.inc.php (+54 lines)
Added Link Here 
1
<?php
2
/**
3
 * @defgroup notification_form
4
 */
5
6
/**
7
 * @file classes/notification/form/NotificationSettingsForm.inc.php
8
 *
9
 * Copyright (c) 2000-2008 John Willinsky
10
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
11
 *
12
 * @class PKPNotificationSettingsForm
13
 * @ingroup notification_form
14
 *
15
 * @brief Form to edit notification settings.
16
 */
17
18
// $Id: PKPNotificationSettingsForm.inc.php,v 1.5 2008/11/05 00:45:13 mcrider Exp $
19
20
21
import('form.Form');
22
23
class PKPNotificationSettingsForm extends Form {
24
	/**
25
	 * Constructor.
26
	 */
27
	function PKPNotificationSettingsForm() {
28
		parent::Form('notification/settings.tpl');
29
		
30
		// Validation checks for this form
31
		$this->addCheck(new FormValidatorPost($this));
32
	}
33
34
	/**
35
	 * Display the form.
36
	 */
37
	function display() {
38
		$user = Request::getUser();
39
		$userId = $user->getUserId();
40
41
		$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
42
		$notificationSettings = $notificationSettingsDao->getNotificationSettings($userId);
43
		$emailSettings = $notificationSettingsDao->getNotificationEmailSettings($userId);
44
45
		$templateMgr =& TemplateManager::getManager();
46
		$templateMgr->assign('notificationSettings', $notificationSettings);
47
		$templateMgr->assign('emailSettings', $emailSettings);
48
		$templateMgr->assign('titleVar', Locale::translate('common.title'));
49
		$templateMgr->assign('userVar', Locale::translate('common.user'));
50
		return parent::display();
51
	}
52
}
53
54
?>
(-)classes/security/AccessKeyDAO.inc.php (-1 / +25 lines)
 Lines 41-46    Link Here 
41
		unset($result);
41
		unset($result);
42
		return $accessKey;
42
		return $accessKey;
43
	}
43
	}
44
	
45
	/**
46
	 * Retrieve a accessKey object user ID.
47
	 * @param $context string
48
	 * @param $userId int
49
	 * @return AccessKey
50
	 */
51
	function &getAccessKeyByUserId($context, $userId) {
52
		$result =& $this->retrieve(
53
			sprintf(
54
				'SELECT * FROM access_keys WHERE context = ? AND user_id = ? AND expiry_date > %s',
55
				$this->datetimeToDB(Core::getCurrentDate())
56
			),
57
			array($context, $userId)
58
		);
59
60
		$returner = null;
61
		if ($result->RecordCount() != 0) {
62
			$returner =& $this->_returnAccessKeyFromRow($result->GetRowAssoc(false));
63
		}
64
		$result->Close();
65
		unset($result);
66
		return $returner;
67
	}
44
68
45
	/**
69
	/**
46
	 * Retrieve a accessKey object by key.
70
	 * Retrieve a accessKey object by key.
 Lines 118-124    Link Here 
118
	 */
142
	 */
119
	function updateAccessKey(&$accessKey) {
143
	function updateAccessKey(&$accessKey) {
120
		return $this->update(
144
		return $this->update(
121
			sprintf('UPDATE accessKeys
145
			sprintf('UPDATE access_keys
122
				SET
146
				SET
123
					key_hash = ?,
147
					key_hash = ?,
124
					expiry_date = %s,
148
					expiry_date = %s,
(-)classes/template/PKPTemplateManager.inc.php (-1 / +1 lines)
 Lines 415-421    Link Here 
415
			if (isset($params['name'])) {
415
			if (isset($params['name'])) {
416
				// build image tag with standarized size of 16x16
416
				// build image tag with standarized size of 16x16
417
				$disabled = (isset($params['disabled']) && !empty($params['disabled']));
417
				$disabled = (isset($params['disabled']) && !empty($params['disabled']));
418
				if (!isset($params['path'])) $params['path'] = 'templates/images/icons/';
418
				if (!isset($params['path'])) $params['path'] = 'lib/pkp/templates/images/icons/';
419
				$iconHtml = '<img src="' . $smarty->get_template_vars('baseUrl') . '/' . $params['path'];
419
				$iconHtml = '<img src="' . $smarty->get_template_vars('baseUrl') . '/' . $params['path'];
420
				$iconHtml .= $params['name'] . ($disabled ? '_disabled' : '') . '.gif" width="16" height="14" alt="';
420
				$iconHtml .= $params['name'] . ($disabled ? '_disabled' : '') . '.gif" width="16" height="14" alt="';
421
421
(-)locale/en_US/common.xml (+46 lines)
 Lines 245-250    Link Here 
245
	<message key="navigation.stepNumber">Step {$step}</message>
245
	<message key="navigation.stepNumber">Step {$step}</message>
246
	<message key="navigation.userHome">User Home</message>
246
	<message key="navigation.userHome">User Home</message>
247
	<message key="navigation.user">User</message>
247
	<message key="navigation.user">User</message>
248
	<message key="notification.allow">Allow these types of notifications to appear in my notification feed.</message>
249
	<message key="notification.confirmError">There was an error confirming your subscription.</message>
250
	<message key="notification.confirmSuccess">You have been successfully subscribed.</message>
251
	<message key="notification.email">Send me an email for these types of notifications.</message>
252
	<message key="notification.location">Go To URL</message>
253
	<message key="notification.mailList">Notification mailing list</message>
254
	<message key="notification.mailListDescription">Enter your email address to receive immediate notifications of important new content added to the journal.</message>
255
	<message key="notification.mailList.privacyProtection">Privacy protection policy</message>
256
	<message key="notification.mailList.protectedContent"><![CDATA[<a href="{$subscribeUrl}">Subscribe</a> to protected content.]]></message>
257
	<message key="notification.mailList.submit"><![CDATA[Or <a href="{$submitUrl}">submit</a> an article?]]></message>
258
	<message key="notification.mailList.review"><![CDATA[Want to also <a href="{$reviewUrl}">review</a>?]]></message>
259
	<message key="notification.noneExist">You have no notifications at this time.</message>
260
	<message key="notification.notification">Notification</message>	
261
	<message key="notification.notifications">Notifications</message>	
262
	<message key="notification.notificationsNew">({$numNew} new)</message>
263
	<message key="notification.notificationsDescription">You have {$unreadCount} unread notifications and {$readCount} read notifications.<![CDATA[  <a href="{$settingsUrl}">Click here</a> to change your notification settings.]]></message>
264
	<message key="notification.notificationsPublicDescription">This page shows important updates associated with this journal such as new issues or announcements.  You may subscribe to these notifications through RSS feeds (by clicking on the images to the right), or <![CDATA[  <a href="{$emailUrl}">through email.</a>]]></message>
265
	<message key="notification.settings">Notification Settings</message>
266
	<message key="notification.settingsDescription">Select the system events that you wish to be notified about.  Unchecking an item will prevent notifications of the event from showing up in your notification feed.</message>
267
	<message key="notification.subscribeError">Your email address is already subscribed to notifications.</message>
268
	<message key="notification.subscribeSuccess">An email has been sent to the address you specified.  Please click on the confirmation link in the email to add yourself to the mailing list.</message>
269
	<message key="notification.reminderError">There was an error sending your password, please ensure you've entered your email address correctly.</message>
270
	<message key="notification.reminderSent">Your new password has been sent to the email address provided.</message>
271
	<message key="notification.type.articleSubmitted">A new article, "{$param}", has been submitted.</message>
272
	<message key="notification.type.copyeditComment">A copyeditor has left a comment on "{$param}".</message>
273
	<message key="notification.type.editing">Editing Events</message>
274
	<message key="notification.type.editorDecisionComment">A comment has been left on the editor decision for "{$param}".</message>
275
	<message key="notification.type.galleyAdded">A galley has been added for "{$param}".</message>
276
	<message key="notification.type.galleyModified">A galley has been modified for "{$param}".</message>
277
	<message key="notification.type.issuePublished">An issue has been published.</message>
278
	<message key="notification.type.layoutComment">A comment has been left about "{$param}'s" layout.</message>
279
	<message key="notification.type.metadataModified">"{$param}'s" metadata has been modified.</message>
280
	<message key="notification.type.newAnnouncement">A new announcement has been created.</message>	
281
	<message key="notification.type.proofreadComment">A comment has been left by a proofreader on "{$param}".</message>
282
	<message key="notification.type.reviewerComment">A reviewer has commented on "{$param}".</message>
283
	<message key="notification.type.reviewerFormComment">A review form review has been submitted for "{$param}".</message>
284
	<message key="notification.type.reviewing">Reviewing Events</message>
285
	<message key="notification.type.site">Site Events</message>
286
	<message key="notification.type.submissionComment">An editor has made a comment on "{$param}".</message>
287
	<message key="notification.type.submissions">Submission Events</message>
288
	<message key="notification.type.suppFileAdded">A supplementary file has been added to "{$param}".</message>
289
	<message key="notification.type.suppFileModified">"{$param}'s" supplementary file(s) has been modified.</message>
290
	<message key="notification.type.userComment">A reader has made a comment on "{$param}"</message>
291
	<message key="notification.unsubscribeDescription">Enter your email address and password below to unsubscribe from email notifications.  If you do not remember your password, leave the password field blank and a new one will be emailed to you at the given email address.</message>	
292
	<message key="notification.unsubscribeError">There was an error unsubscribing you.  Please ensure your email address and password are correct.</message>
293
	<message key="notification.unsubscribeSuccess">You were successfully unsubscribed.</message>	
248
	<message key="search.abstract">Abstract</message>
294
	<message key="search.abstract">Abstract</message>
249
	<message key="search.allFields">All</message>
295
	<message key="search.allFields">All</message>
250
	<message key="search.coverage">Coverage</message>
296
	<message key="search.coverage">Coverage</message>
(-)pages/notification/NotificationHandler.inc.php (+278 lines)
Added Link Here 
1
<?php
2
3
/**
4
 * @file NotificationHandler.inc.php
5
 *
6
 * Copyright (c) 2000-2008 John Willinsky
7
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
8
 *
9
 * @class NotificationHandler
10
 * @ingroup pages_help
11
 *
12
 * @brief Handle requests for viewing notifications. 
13
 */
14
15
import('core.PKPHandler');
16
import('notification.Notification');
17
18
class NotificationHandler extends PKPHandler {
19
20
	/**
21
	 * Display help table of contents.
22
	 */
23
	function index() {
24
		parent::validate();
25
		parent::setupTemplate();
26
		$templateMgr =& TemplateManager::getManager();
27
		
28
		$user = Request::getUser();
29
		if(isset($user)) {
30
			$userId = $user->getUserId();
31
			$templateMgr->assign('isUserLoggedIn', true);
32
		} else {
33
			$userId = 0;
34
			$templateMgr->assign('emailUrl', Request::url(null, 'notification', 'subscribeMailList'));
35
			$templateMgr->assign('isUserLoggedIn', false);
36
		}
37
38
		$notificationDao =& DAORegistry::getDAO('NotificationDAO');
39
		$notifications = $notificationDao->getNotificationsByUserId($userId);
40
		
41
		$templateMgr->assign('notifications', $notifications);
42
		$templateMgr->assign('unread', $notificationDao->getUnreadNotificationCount($userId));
43
		$templateMgr->assign('read', $notificationDao->getReadNotificationCount($userId));
44
		$templateMgr->assign('url', Request::url(null, 'notification', 'settings'));
45
		$templateMgr->display('notification/index.tpl');
46
	}
47
	
48
	/**
49
	 * Delete a notification
50
	 */
51
	function delete($args) {
52
		parent::validate();
53
		
54
		$notificationId = array_shift($args);
55
		if (array_shift($args) == 'ajax') {
56
			$isAjax = true;
57
		} else $isAjax = false;
58
		
59
		$user = Request::getUser();
60
		if(isset($user)) {
61
			$userId = $user->getUserId();
62
			$notificationDao =& DAORegistry::getDAO('NotificationDAO');
63
			$notifications = $notificationDao->deleteNotificationById($notificationId, $userId);
64
		}
65
		
66
		if (!$isAjax) Request::redirect(null, 'notification');
67
	}
68
69
	/**
70
	 * View and modify notification settings
71
	 */
72
	function settings() {
73
		parent::validate();
74
		parent::setupTemplate();
75
76
77
		$user = Request::getUser();
78
		if(isset($user)) {
79
			import('notification.form.NotificationSettingsForm');
80
			$notificationSettingsForm =& new NotificationSettingsForm();
81
			$notificationSettingsForm->display();
82
		} else Request::redirect(null, 'notification');
83
	}
84
	
85
	/**
86
	 * Save user notification settings
87
	 */
88
	function saveSettings() {
89
		parent::validate();
90
		
91
		import('notification.form.NotificationSettingsForm');
92
		
93
		$notificationSettingsForm =& new NotificationSettingsForm();
94
		$notificationSettingsForm->readInputData();
95
		
96
		if ($notificationSettingsForm->validate()) {
97
			$notificationSettingsForm->execute();
98
			Request::redirect(null, 'notification', 'settings');
99
		} else {
100
			parent::setupTemplate(true);
101
			$notificationSettingsForm->display();
102
		}
103
	}
104
	
105
	/**
106
	 * Fetch the existing or create a new URL for the user's RSS feed
107
	 */
108
	function getNotificationFeedUrl($args) {
109
		$user = Request::getUser();
110
		if(isset($user)) {
111
			$userId = $user->getUserId();
112
		} else $userId = 0;
113
		
114
		$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
115
		$feedType = array_shift($args);
116
117
		$token = $notificationSettingsDao->getRSSTokenByUserId($userId);
118
		
119
		if ($token) {
120
			Request::redirect(null, 'notification', 'notificationFeed', array($feedType, $token));
121
		} else {
122
			$token = $notificationSettingsDao->insertNewRSSToken($userId);
123
			Request::redirect(null, 'notification', 'notificationFeed', array($feedType, $token));
124
		}
125
	}
126
	
127
	/**
128
	 * Fetch the actual RSS feed
129
	 */
130
	function notificationFeed($args) {
131
		if(isset($args[0]) && isset($args[1])) {
132
			$type = $args[0];
133
			$token = $args[1];
134
		} else return false;
135
136
		$application = PKPApplication::getApplication();
137
		$appName = $application->getNameKey();
138
		
139
		$site =& Request::getSite();
140
		$siteTitle = $site->getSiteTitle();
141
	
142
		$notificationDao =& DAORegistry::getDAO('NotificationDAO');
143
		$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
144
		
145
		$userId = $notificationSettingsDao->getUserIdByRSSToken($token);
146
		$notifications = $notificationDao->getNotificationsByUserId($userId);
147
148
		// Make sure the feed type is specified and valid
149
		$typeMap = array(
150
			'rss' => 'rss.tpl',
151
			'rss2' => 'rss2.tpl',
152
			'atom' => 'atom.tpl'
153
		);
154
		$mimeTypeMap = array(
155
			'rss' => 'application/rdf+xml',
156
			'rss2' => 'application/rss+xml',
157
			'atom' => 'application/atom+xml'
158
		);
159
		if (!isset($typeMap[$type])) return false;
160
161
		$versionDao =& DAORegistry::getDAO('VersionDAO');
162
		$version = $versionDao->getCurrentVersion();
163
164
		$templateMgr =& TemplateManager::getManager();
165
		$templateMgr->assign('version', $version->getVersionString());
166
		$templateMgr->assign('selfUrl', Request::getCompleteUrl()); 
167
		$templateMgr->assign('locale', Locale::getPrimaryLocale()); 
168
		$templateMgr->assign('appName', $appName);
169
		$templateMgr->assign('siteTitle', $siteTitle);
170
		$templateMgr->assign_by_ref('notifications', $notifications->toArray());
171
172
		$templateMgr->display(Core::getBaseDir() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 
173
			'pkp' . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR . 'notification' . DIRECTORY_SEPARATOR . $typeMap[$type], $mimeTypeMap[$type]);
174
175
		return true;
176
	}
177
178
	/**
179
	 * Display the public notification email subscription form
180
	 */
181
	function subscribeMailList() {
182
		parent::setupTemplate();
183
		$templateMgr = &TemplateManager::getManager();
184
		$templateMgr->assign('new', true);
185
186
		$user = Request::getUser();
187
		//	FIXME: Need to abstract subscription enabled check
188
		//	import('payment.PaymentManager');
189
		//	$subscriptionEnabled = PaymentManager::isConfigured();
190
				
191
		if(!isset($user)) {
192
			// $templateMgr->assign('subscriptionEnabled', $subscriptionEnabled);
193
			
194
			if($userEmail = Request::getUserVar('email')) {
195
				$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
196
				if($password = $notificationSettingsDao->subscribeGuest($userEmail)) {
197
					Notification::sendMailingListEmail($userEmail, $password, 'NOTIFICATION_MAILLIST_WELCOME');
198
					$templateMgr->assign('success', "notification.subscribeSuccess");
199
					$templateMgr->display('notification/maillist.tpl');
200
				} else {
201
					$templateMgr->assign('error', "notification.subscribeError");
202
					$templateMgr->display('notification/maillist.tpl');
203
				
204
				}
205
			} else {
206
				$templateMgr->display('notification/maillist.tpl');
207
			}
208
		} else Request::redirect(null, 'notification');
209
	}
210
211
	/**
212
	 * Display the public notification email subscription form
213
	 */
214
	function confirmMailListSubscription($args) {
215
		parent::setupTemplate();
216
		$keyHash = array_shift($args);
217
		$email = array_shift($args);
218
		
219
		$templateMgr =& TemplateManager::getManager();
220
		$templateMgr->assign('confirm', true);
221
222
		$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
223
		$settingId = $notificationSettingsDao->getMailListSettingId($email);
224
225
		$accessKeyDao =& DAORegistry::getDAO('AccessKeyDAO');
226
		$accessKey = $accessKeyDao->getAccessKeyByKeyHash('MailListContext', $settingId, $keyHash);
227
	
228
		if($accessKey) {
229
			$notificationSettingsDao->confirmMailListSubscription($settingId);
230
			$templateMgr->assign('success', "notification.confirmSuccess");
231
			$templateMgr->display('notification/maillist.tpl');
232
		} else {
233
			$templateMgr->assign('error', "notification.confirmError");
234
			$templateMgr->display('notification/maillist.tpl');
235
		}
236
	}
237
238
	/**
239
	 * Display the public notification email subscription form
240
	 */
241
	function unsubscribeMailList() {
242
		parent::setupTemplate();
243
		$templateMgr =& TemplateManager::getManager();
244
		$templateMgr->assign('remove', true);
245
		
246
		$user = Request::getUser();
247
		if(!isset($user)) {
248
			$userEmail = Request::getUserVar('email');
249
			$userPassword = Request::getUserVar('password');
250
			
251
			if($userEmail != '' && $userPassword != '') {
252
				$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
253
				if($notificationSettingsDao->unsubscribeGuest($userEmail, $userPassword)) {
254
					$templateMgr->assign('success', "notification.unsubscribeSuccess");
255
					$templateMgr->display('notification/maillist.tpl');
256
				} else {
257
					$templateMgr->assign('error', "notification.unsubscribeError");
258
					$templateMgr->display('notification/maillist.tpl');
259
				}
260
			} else if($userEmail != '' && $userPassword == '') {
261
				$notificationSettingsDao =& DAORegistry::getDAO('NotificationSettingsDAO');
262
				if($newPassword = $notificationSettingsDao->resetPassword($userEmail)) {
263
					Notification::sendMailingListEmail($userEmail, $newPassword, 'NOTIFICATION_MAILLIST_PASSWORD');
264
					$templateMgr->assign('success', "notification.reminderSent");
265
					$templateMgr->display('notification/maillist.tpl');
266
				} else {
267
					$templateMgr->assign('error', "notification.reminderError");
268
					$templateMgr->display('notification/maillist.tpl');
269
				}
270
			} else {		
271
				$templateMgr->assign('remove', true);
272
				$templateMgr->display('notification/maillist.tpl');
273
			}
274
		} else Request::redirect(null, 'notification');
275
	}
276
}
277
278
?>
(-)pages/notification/index.php (+23 lines)
Added Link Here 
1
<?php
2
3
/**
4
 * @defgroup pages_notification
5
 */
6
 
7
/**
8
 * @file pages/notification/index.php
9
 *
10
 * Copyright (c) 2000-2008 John Willinsky
11
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
12
 *
13
 * @ingroup pages_notification
14
 * @brief Handle requests for viewing notifications. 
15
 *
16
 */
17
18
19
define('HANDLER_CLASS', 'NotificationHandler');
20
21
import('pages.notification.NotificationHandler');
22
23
?>
(-)templates/notification/atom.tpl (+43 lines)
Added Link Here 
1
{**
2
 * atom.tpl
3
 *
4
 * Copyright (c) 2003-2008 John Willinsky
5
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
6
 *
7
 * Atom feed template
8
 *
9
 * $Id: atom.tpl,v 1.3 2008/06/11 21:52:26 asmecher Exp $
10
 *}
11
<?xml version="1.0" encoding="{$defaultCharset|escape}"?>
12
<feed xmlns="http://www.w3.org/2005/Atom">
13
	<id>{$selfUrl}</id>
14
	<title>{$siteTitle} {translate key="notification.notifications"}</title>
15
16
	<link rel="self" type="application/atom+xml" href="{$selfUrl}" />
17
18
	<generator uri="http://pkp.sfu.ca/ojs/" version="{$version|escape}">{translate key=$appName}</generator>
19
20
{foreach from=$notifications item=notification}
21
	<entry>
22
		<id>$notification->getNotificationId()</id>
23
		<title>{translate key="notification.notification"} : {$notification->getDateCreated()|date_format:"%a, %d %b %Y %T %z"}</title>
24
		{if $notification->getLocation() != null}
25
			<link rel="alternate" href="{$notification->getLocation()}" />					
26
		{else}
27
			<link rel="alternate" href="{url page="notification"}" />					
28
		{/if}
29
30
		<summary type="html" xml:base="{if $notification->getLocation() != null}{$notification->getLocation()}{else}{url page="notification"}{/if}">
31
			{if $notification->getIsLocalized()}
32
				{translate key=$notification->getContents() param=$notification->getParam()}
33
			{else}
34
				{$notification->getContents()}
35
			{/if}
36
		</summary>
37
38
		<published>{$notification->getDateCreated()|date_format:"%Y-%m-%dT%T%z"|regex_replace:"/00$/":":00"}</published>
39
	</entry>
40
{/foreach}
41
</feed>
42
43
(-)templates/notification/index.tpl (+85 lines)
Added Link Here 
1
{**
2
 * index.tpl
3
 *
4
 * Copyright (c) 2000-2008 John Willinsky
5
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
6
 *
7
 * Display list of notifications. 
8
 *
9
 *}
10
{strip}
11
{assign var="pageTitle" value="notification.notifications"}
12
{include file="common/header.tpl"}
13
{/strip}
14
15
<table width="100%">
16
	<tr>
17
		<td>{if $isUserLoggedIn}
18
				<p>{translate key="notification.notificationsDescription" unreadCount=$unread readCount=$read settingsUrl=$url}</p>
19
			{else}
20
				<p>{translate key="notification.notificationsPublicDescription" emailUrl=$emailUrl}</p>
21
			{/if}
22
		</td>
23
		<td><ul class="plain">
24
			<li><a href="{url op="getNotificationFeedUrl" path="rss"}" class="icon"><img src="{$baseUrl}/lib/pkp/templates/images/rss10_logo.gif" alt="RSS 1.0"/></a></li>
25
			<li><a href="{url op="getNotificationFeedUrl" path="rss2"}" class="icon"><img src="{$baseUrl}/lib/pkp/templates/images/rss20_logo.gif" alt="RSS 2.0"/></a></li>
26
			<li><a href="{url op="getNotificationFeedUrl" path="atom"}" class="icon"><img src="{$baseUrl}/lib/pkp/templates/images/atom10_logo.gif" alt="Atom 1.0"/></a></li>
27
		</ul></td>
28
	</tr>
29
</table>
30
31
<br/>
32
33
<div id="notifications">
34
{iterate from=notifications item=notification}
35
	<table width="100%" class="notifications">
36
		<tr>
37
			<td width="25"><img src="{$notification->getIconLocation()}" alt="&#187"/></td>
38
			<td class="notificationContent" colspan="2" width="80%">
39
				{$notification->getDateCreated()}
40
			</td>
41
			{if $notification->getLocation() != null}
42
				<td id="notificationLink" class="notificationFunction" style="min-width:60px"><a href="{$notification->getLocation()}">{translate key="notification.location"}</a></td>
43
			{else}
44
				<td id="notificationLink" class="notificationFunction"></td>
45
			{/if}
46
			{if $isUserLoggedIn}
47
				<td id="notificationDelete" class="notificationFunction"><a id="notificationDeleteLink" href="{url op="delete" path=$notification->getNotificationId()}">{translate key="common.delete"}</a></td>
48
			{/if}
49
		</tr>
50
		<tr>
51
			<td width="25">&nbsp;</td>
52
			<td class="notificationContent">
53
				{if $notification->getIsUnread()}
54
					{if $notification->getIsLocalized()}<p style="font-weight: bold">{translate key=$notification->getContents() param=$notification->getParam()}</p>
55
					{else}<p style="font-weight: bold">{$notification->getContents()}{/if}
56
				{else}
57
					{if $notification->getIsLocalized()}<p>{translate key=$notification->getContents() param=$notification->getParam()}</p>
58
					{else}<p>{$notification->getContents()}</p>{/if}	
59
				{/if}
60
			</td>
61
		</tr>
62
	</table>
63
	<div class="separator" style="margin-left:25px"></div>
64
{/iterate}
65
{if $notifications->wasEmpty()}
66
	<table class="notifications">
67
		<tr>
68
			<td colspan="2" class="nodata"><h5>{translate key="notification.noneExist"}</h5></td>
69
		</tr>
70
		<tr>
71
			<td colspan="2" class="endseparator">&nbsp;</td>
72
		</tr>
73
	</table>
74
{else}
75
	<table class="notifications">
76
		<tr>
77
			<td align="left">{page_info iterator=$notifications}</td>
78
			<td align="right">{page_links anchor="notifications" name="notifications" iterator=$notifications}</td>
79
		</tr>
80
	</table>
81
{/if}
82
83
</div>
84
85
{include file="common/footer.tpl"}
(-)templates/notification/maillist.tpl (+93 lines)
Added Link Here 
1
{**
2
 * index.tpl
3
 *
4
 * Copyright (c) 2000-2008 John Willinsky
5
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
6
 *
7
 * Displays the notification settings page and unchecks  
8
 *
9
 *}
10
{strip}
11
{assign var="pageTitle" value="notification.mailList"}
12
{include file="common/header.tpl"}
13
{/strip}
14
15
{if $new}
16
	<p><span class="instruct">{translate key="notification.mailListDescription"}</span></p>
17
	<br />
18
19
	{if $error}
20
		<p><span class="formError">{translate key="$error"}</span></p>
21
	{/if}
22
	
23
	{if $success}
24
		<p><span class="formSuccess">{translate key="$success"}</span></p>
25
	{/if}
26
27
	<form id="notificationSettings" method="post" action="{url op="subscribeMailList"}">
28
	
29
	<table class="data" width="100%">
30
		<tr valign="top">
31
			<td class="label" width="5%">{translate key="email.email"}</td>
32
			<td class="value" width="45%"><input type="text" name="email" size="30" maxlength="90" class="textField" /></td>
33
		</tr>
34
		<tr valign="top">
35
			<td width="5%">&nbsp;</td>
36
			<td><p><input type="submit" value="{translate key="form.submit"}" class="button defaultButton" /></p></td>
37
		</tr>
38
	</table>
39
	</form>
40
	
41
	<ul class="plain" style="margin-left:10%">
42
		{url|assign:"url" page="user" op="register"}
43
		<li>&#187; {translate key="notification.mailList.review" reviewUrl=$url} </li>
44
		{url|assign:"url" page="information" op="authors"}
45
		<li>&#187; {translate key="notification.mailList.submit" submitUrl=$url} </li>
46
		{** need to abstract subscription enabled check
47
		* assign var=subscribeUrl value="url op="subscriptions""
48
		* if $subscriptionEnabled <li>&#187; translate key="notification.mailList.protectedContent" subscribeUrl=$subscribeUrl
49
		*}
50
		<li>&#187; <a href="{url op="protectionPolicy"}">{translate key="notification.mailList.privacyProtection"}</a></li>
51
	<ul>
52
{elseif $remove}
53
	<p><span class="instruct">{translate key="notification.unsubscribeDescription"}</span></p>
54
	<br />
55
56
	{if $error}
57
		<p><span class="formError">{translate key="$error"}</span></p>
58
	{/if}
59
	
60
	{if $success}
61
		<p><span class="formSuccess">{translate key="$success"}</span></p>
62
	{/if}
63
	
64
	<form id="notificationSettings" method="post" action="{url op="unsubscribeMailList"}">
65
	<table class="data" width="100%">
66
		<tr valign="top">
67
			<td class="label" width="5%">{translate key="email.email"}</td>
68
			<td class="value" width="45%"><input type="text" name="email" size="30" maxlength="90" class="textField" /></td>
69
		</tr>
70
		<tr valign="top">
71
			<td class="label" width="5%">{translate key="user.password"}</td>
72
			<td class="value" width="45%"><input type="text" name="password" size="30" maxlength="90" class="textField" /></td>
73
		</tr>
74
		<tr valign="top">
75
			<td width="5%">&nbsp;</td>
76
			<td><p><input type="submit" value="{translate key="form.submit"}" class="button defaultButton" /></p></td>
77
		</tr>
78
	</table>
79
	
80
	</form>
81
{elseif $confirm}
82
	{if $error}
83
		<p><span class="formError">{translate key="$error"}</span></p>
84
	{/if}
85
	
86
	{if $success}
87
		<p><span class="formSuccess">{translate key="$success"}</span></p>
88
	{/if}
89
{/if}
90
91
</form>
92
93
{include file="common/footer.tpl"}
(-)templates/notification/rss.tpl (+53 lines)
Added Link Here 
1
{**
2
 * rss.tpl
3
 *
4
 * Copyright (c) 2003-2008 John Willinsky
5
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
6
 *
7
 * RSS feed template
8
 *
9
 * $Id: rss.tpl,v 1.3 2008/06/11 21:52:26 asmecher Exp $
10
 *}
11
<?xml version="1.0" encoding="{$defaultCharset|escape}"?>
12
<rdf:RDF
13
	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
14
	xmlns="http://purl.org/rss/1.0/"
15
	xmlns:dc="http://purl.org/dc/elements/1.1/"
16
	xmlns:prism="http://prismstandard.org/namespaces/1.2/basic/">
17
    
18
	<channel rdf:about="{$baseUrl}">
19
		<title>{$siteTitle} {translate key="notification.notifications"}</title>
20
		<link>{$selfUrl}</link>
21
		<language>{$locale|replace:'_':'-'|strip|escape:"html"}</language>
22
		<items>
23
			{foreach from=$notifications item=notification}
24
			<rdf:Seq>
25
				<rdf:li rdf:resource="{url page="notification"}"/>
26
			</rdf:Seq>
27
			{/foreach}
28
		</items>
29
	</channel>
30
31
	{foreach from=$notifications item=notification}
32
	<item rdf:about="{url page="notification"}">
33
		<title>{translate key="notification.notification"} : {$notification->getDateCreated()|date_format:"%a, %d %b %Y %T %z"}</title>
34
		<link>
35
			{if $notification->getLocation() != null}
36
				{$notification->getLocation()}
37
			{else}
38
				{url page="notification"}
39
			{/if}
40
		</link>
41
		<description>
42
			{if $notification->getIsLocalized()}
43
				{translate key=$notification->getContents() param=$notification->getParam()}
44
			{else}
45
				{$notification->getContents()}
46
			{/if}
47
		</description>	
48
		<dc:creator>{$siteTitle|strip|escape:"html"}</dc:creator>
49
		<dc:date>{$notification->getDateCreated()|date_format:"%Y-%m-%d"}</dc:date>
50
	</item>
51
	{/foreach}
52
53
</rdf:RDF>
(-)templates/notification/rss2.tpl (+45 lines)
Added Link Here 
1
{**
2
 * rss2.tpl
3
 *
4
 * Copyright (c) 2003-2008 John Willinsky
5
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
6
 *
7
 * RSS 2 feed template
8
 *
9
 * $Id: rss2.tpl,v 1.3 2008/06/11 21:52:26 asmecher Exp $
10
 *}
11
<?xml version="1.0" encoding="{$defaultCharset|escape}"?>
12
<rss version="2.0">
13
	<channel>
14
		{* required elements *}
15
		<title>{$siteTitle} {translate key="notification.notifications"}</title>
16
		<link>{$selfUrl}</link>
17
18
		{* optional elements *}
19
	    <language>{$locale|replace:'_':'-'|strip|escape:"html"}</language>
20
		<generator>{translate key=$appName} {$version|escape}</generator>
21
		<docs>http://blogs.law.harvard.edu/tech/rss</docs>
22
		<ttl>60</ttl>
23
24
		{foreach from=$notifications item=notification}
25
			<item>
26
				<title>{translate key="notification.notification"} : {$notification->getDateCreated()|date_format:"%a, %d %b %Y %T %z"}</title>
27
				<link>
28
					{if $notification->getLocation() != null}
29
						{$notification->getLocation()}
30
					{else}
31
						{url page="notification"}
32
					{/if}
33
				</link>
34
				<description>
35
					{if $notification->getIsLocalized()}
36
						{translate key=$notification->getContents() param=$notification->getParam()}
37
					{else}
38
						{$notification->getContents()}
39
					{/if}
40
				</description>		
41
				<pubDate>{$notification->getDateCreated()|date_format:"%a, %d %b %Y %T %z"}</pubDate>
42
			</item>
43
		{/foreach}
44
	</channel>
45
</rss>
(-)xml/pkp_schema.xml (+62 lines)
 Lines 331-336    Link Here 
331
		</index>
331
		</index>
332
	</table>
332
	</table>
333
333
334
	<!--
335
	  *
336
	  * TABLE notifications
337
	  *
338
	  -->
339
	<table name="notifications">
340
		<field name="notification_id" type="I8">
341
			<KEY />
342
			<AUTOINCREMENT />
343
		</field>
344
		<field name="user_id" type="I8">
345
			<NOTNULL/>
346
		</field>
347
		<field name="date_created" type="T">
348
			<NOTNULL/>
349
		</field>
350
		<field name="date_read" type="T" />
351
		<field name="contents" type="C2" size="255" >
352
			<NOTNULL/>
353
		</field>
354
		<field name="param" type="C2" size="255" />
355
		<field name="location" type="C2" size="255" />
356
		<field name="is_localized" type="I1" >
357
			<NOTNULL/>
358
			<DEFAULT VALUE="1"/>
359
		</field>
360
		<field name="product" type="C2" size="20" />
361
		<field name="context" type="I8">
362
			<NOTNULL/>
363
		</field>
364
		<field name="assoc_type" type="I8">
365
			<NOTNULL/>
366
		</field>
367
		<descr>Stores notifications for users as created by the system after certain operations.</descr>
368
	</table>
369
	
370
	<!--
371
	  *
372
	  * TABLE notification_settings
373
	  *
374
	  -->
375
	<table name="notification_settings">
376
		<field name="setting_id" type="I8">
377
			<KEY />
378
			<AUTOINCREMENT />
379
		</field>
380
		<field name="setting_name" type="C2" size="64">
381
			<NOTNULL/>
382
		</field>
383
		<field name="setting_value" type="X">
384
			<NOTNULL/>
385
		</field>
386
		<field name="user_id" type="I8">
387
			<NOTNULL/>
388
		</field>
389
		<field name="product" type="C2" size="20" />
390
		<field name="context" type="I8">
391
			<NOTNULL/>
392
		</field>
393
		<descr>Lists all notifications types for each user that they do NOT want to be informed of, and also contains a list of RSS feed tokens for each user.</descr>
394
	</table>
395
	
334
	<!-- OAI Tables -->
396
	<!-- OAI Tables -->
335
	
397
	
336
	<!--
398
	<!--

Return to bug 3922