tiki-webmail.php 32.4 KB
Newer Older
lrargerich's avatar
lrargerich committed
1
<?php
changi67's avatar
changi67 committed
2 3 4
/**
 * @package tikiwiki
 */
5
// (c) Copyright 2002-2016 by authors of the Tiki Wiki CMS Groupware Project
6
//
7 8
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
changi67's avatar
changi67 committed
9
// $Id$
10

11
$section = 'webmail';
rjsmelo's avatar
rjsmelo committed
12 13
require_once('tiki-setup.php');
include_once('lib/webmail/webmaillib.php');
14
$contactlib = TikiLib::lib('contact');
lrargerich's avatar
lrargerich committed
15

16
$access->check_feature('feature_webmail');
rjsmelo's avatar
rjsmelo committed
17
$access->check_permission_either(['tiki_p_use_webmail', 'tiki_p_use_group_webmail']);
lrargerich's avatar
lrargerich committed
18

rjsmelo's avatar
rjsmelo committed
19 20 21 22
require_once('lib/webmail/net_pop3.php');
require_once('lib/mail/mimelib.php');
include_once('lib/webmail/tikimaillib.php');
require_once('lib/filegals/filegallib.php');
23

24
// AJAX_TODO
25 26 27
/**
 * @param $inUrl
 */
28 29
function handleWebmailRedirect($inUrl)
{
rjsmelo's avatar
rjsmelo committed
30
	header('location: tiki-webmail.php?' . $inUrl);
31
	exit;
32 33
}

34
$access->check_user($user);
lrargerich's avatar
lrargerich committed
35

36 37 38 39 40
// check category permissions on group accounts
if (isset($_REQUEST['locSection']) && $_REQUEST['locSection'] == 'settings') {
	$id = false;
	if (isset($_REQUEST['accountId'])) {
		$id = $_REQUEST['accountId'];
rjsmelo's avatar
rjsmelo committed
41
	} elseif (isset($_REQUEST['remove'])) {
42
		$id = $_REQUEST['remove'];
rjsmelo's avatar
rjsmelo committed
43
	} elseif (isset($_REQUEST['current'])) {
44 45 46
		$id = $_REQUEST['current'];
	}
	if ($id) {
rjsmelo's avatar
rjsmelo committed
47
		$objectperms = Perms::get(['type' => 'webmail account', 'object' => $id]);
48
		$acct = $webmaillib->get_webmail_account($user, $id);
rjsmelo's avatar
rjsmelo committed
49 50 51 52 53 54 55
		if (! isset($_REQUEST['current'])) {
			if ($acct['flagsPublic'] == 'y' && ! $objectperms->admin_group_webmail) {
				handleWebmailRedirect(
					'locSection=settings&msg=' . tra(
						'You do not have permission to admin the requested webmail account.'
					)
				);
56 57
			}
		} else {
rjsmelo's avatar
rjsmelo committed
58 59 60 61
			if ($acct['flagsPublic'] == 'y' && ! $objectperms->use_group_webmail) {
				handleWebmailRedirect(
					'locSection=settings&msg=' . tra('You do not have permission to use the requested webmail account.')
				);
62 63 64
			}
		}
	}
65
} else {
66
	$acct = $webmaillib->get_current_webmail_account($user);
67
	if ($acct) {
rjsmelo's avatar
rjsmelo committed
68 69 70 71 72
		$objectperms = Perms::get(['type' => 'webmail account', 'object' => $acct['accountId']]);
		if ($acct['flagsPublic'] == 'y' && ! $objectperms->use_group_webmail) {
			handleWebmailRedirect(
				'locSection=settings&msg=' . tra('You no longer have permission to use your active webmail account.')
			);
73 74 75 76
		}
	}
}

77
$auto_query_args = ['msgid', 'locSection', 'filter', 'folder'];
78

rjsmelo's avatar
rjsmelo committed
79
if (! isset($_REQUEST['locSection'])) {
80
	$_REQUEST['locSection'] = 'mailbox';
lrargerich's avatar
lrargerich committed
81
}
82
$headerlib->add_js('var webmailTimeoutId = null;', 0);
83

84
$smarty->assign('locSection', $_REQUEST['locSection']);
lrargerich's avatar
lrargerich committed
85
// Search if we have to add some contacts
86 87
if (isset($_REQUEST['add_contacts'])) {
	if (isset($_REQUEST['add'])) {
88
		check_ticket('webmail');
rjsmelo's avatar
rjsmelo committed
89
		foreach (array_keys($_REQUEST['add']) as $i) {
90
			$contactlib->replace_contact(
91 92 93 94 95 96
				0,
				$_REQUEST['addFirstName'][$i],
				$_REQUEST['addLastName'][$i],
				$_REQUEST['addemail'][$i],
				$_REQUEST['addNickname'][$i],
				$user
97
			);
98 99
		}
	}
luciash's avatar
luciash committed
100
}
lrargerich's avatar
lrargerich committed
101

102 103 104
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// Read an Email ////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
105

106 107
if ($_REQUEST['locSection'] == 'read') {
	if (isset($_REQUEST['fullheaders'])) {
108 109 110 111
		$smarty->assign('fullheaders', 'y');
	} else {
		$smarty->assign('fullheaders', 'n');
	}
112
	$headerlib->add_js('if (webmailTimeoutId) {window.clearTimeout(webmailTimeoutId);}', 0);
113

114
	$current = $webmaillib->get_current_webmail_account($user);
115 116


117
	$smarty->assign_by_ref('current', $current);
118 119 120

	// connecting with Zend
	try {
121
		$mail = $webmaillib->get_mail_storage();
122 123
	} catch (Exception $e) {
		// do something better with the error
124
		Feedback::error(tra('There was a problem connecting to that account:') . ' ' . $e->getMessage());
125
	}
126

127
	if (isset($_REQUEST['delete_one'])) {
128
		check_ticket('webmail');
rjsmelo's avatar
rjsmelo committed
129
		$aux = $webmail_list[$_REQUEST['msgdel'] - 1];
130
		try {
131 132 133
			$mail->removeMessage($_REQUEST['msgdel']);
			$webmaillib->remove_webmail_message($current['accountId'], $user, $aux['realmsgid']);
			unset($_REQUEST['msgid']);
134
		} catch (Exception $e) {
135
			Feedback::error(tra('There was a problem deleting that email message:') . ' ' . $e->getMessage());
136
		}
137 138
	}

139
	if (isset($_REQUEST['msgid'])) {
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
		try {
			$message = $mail->getMessage($_REQUEST['msgid']);
			$aux = $message->getHeaders()->toArray();
			$realmsgid = preg_replace('/[<>]/', '', $aux['message-id']);
			$smarty->assign('msgid', $_REQUEST['msgid']);
			$smarty->assign('realmsgid', $realmsgid);
			$webmaillib->set_mail_flag($current['accountId'], $user, $realmsgid, 'isRead', 'y');
			$mailsum = $mail->countMessages();
			$numshow = $current['msgs'];

			if ($_REQUEST['msgid'] == $mailsum) {
				$smarty->assign('next', '');
			} else {
				$smarty->assign('next', $_REQUEST['msgid'] + 1);
			}
155

156 157 158 159 160
			if ($_REQUEST['msgid'] > 1) {
				$smarty->assign('prev', $_REQUEST['msgid'] - 1);
			} else {
				$smarty->assign('prev', '');
			}
161 162


rjsmelo's avatar
rjsmelo committed
163
			$attachments = [];
164

165 166 167
			//		if ($message->isMultipart()) {
			//			TODO	deal with attachments here??
			//		}
168

169
			$bodies = $webmaillib->get_mail_content($user, $current['accountId'], $_REQUEST['msgid'], true);
170

171

172 173 174
			for ($i = 0, $count_bodies = count($bodies); $i < $count_bodies; $i++) {
				if ($bodies[$i]['contentType'] == 'text/html') {
					$bod = $bodies[$i]['body'];
175

176 177 178
					// Clean the string using HTML Purifier
					require_once('lib/htmlpurifier_tiki/HTMLPurifier.tiki.php');
					$bod = HTMLPurifier($bod);
179

rjsmelo's avatar
rjsmelo committed
180 181 182
					if (preg_match_all('/<[\/]?body[^>]*>/i', $bod, $m, PREG_OFFSET_CAPTURE) && count($m) > 0 && count(
						$m[0]
					) > 1) {
183 184 185 186 187
						// gets positions of the start and end body tags then substr the bit inbetween
						$bod = substr($bod, $m[0][0][1] + strlen($m[0][0][0]), $m[0][1][1]);
					}
					$bod = strip_tags(
						$bod,
rjsmelo's avatar
rjsmelo committed
188
						'<a><b><i><strong><em><p><blockquote><table><tbody><tr><td><th>' . '<ul><li><img><hr><ol><br><h1><h2><h3><h4><h5><h6><div><span>' . '<font><form><input><textarea><checkbox><select><style>'
189 190 191 192
					);
					// try to close malformed html not fixed by the purifier - because people email Really Bad Things and this messes up *lite.css layout
					$bod = closetags($bod);
					$bodies[$i]['body'] = $bod;
rjsmelo's avatar
rjsmelo committed
193
				} elseif ($bodies[$i]['contentType'] == 'text/plain') {
194 195 196 197
					// reply text
					$smarty->assign('plainbody', format_email_reply($bodies[$i]['body'], $aux['from'], $aux['date']));
					$bodies[$i]['body'] = nl2br($bodies[$i]['body']);
				}// else {
198
				// attachments?
199 200
				//}
			}
201

rjsmelo's avatar
rjsmelo committed
202 203 204
			array_multisort(
				$bodies
			);    // this doesn't do what we need properly but seems to fluke it mostly - TODO a manual re-sort
205

206 207
			$smarty->assign_by_ref('attachs', $attachments);
			$smarty->assign_by_ref('bodies', $bodies);
208

209 210 211 212 213
			try {
				$allbodies = $message->getContent();
			} catch (Exception $e) {
				$allbodies = $e->getMessage();
			}
214

215
			$smarty->assign('allbodies', htmlspecialchars($allbodies));
216

217 218
			// collect addresses for reply
			$to_addresses = $aux['From'];
219

220 221
			// Get email addresses from the 'from' portion
			$to_addresses = explode(',', $to_addresses);
222

223 224 225
			$temp_max = count($to_addresses);
			for ($i = 0; $i < $temp_max; $i++) {
				preg_match('/<([^>]+)>/', $to_addresses[$i], $add);
226

227 228 229
				if (isset($add[1])) {
					$to_addresses[$i] = $add[1];
				}
230
			}
231

232 233
			if (isset($aux['Cc']) || preg_match('/,/', $aux['To'])) {
				$cc_addresses = '';
234

rjsmelo's avatar
rjsmelo committed
235
				if (isset($aux['Cc'])) {
236
					$cc_addresses .= $aux['Cc'];
rjsmelo's avatar
rjsmelo committed
237
				}
238

239
				//add addresses to cc from 'to' field (for 'reply to all')
rjsmelo's avatar
rjsmelo committed
240
				if ($cc_addresses != '') {
241
					$cc_addresses .= ',';
rjsmelo's avatar
rjsmelo committed
242
				}
243

244 245
				$cc_addresses .= $aux['To'];
				$cc_addresses = explode(',', $cc_addresses);
246

247 248 249
				$temp_max = count($cc_addresses);
				for ($i = 0; $i < $temp_max; $i++) {
					preg_match('/<([^>]+)>/', $cc_addresses[$i], $add);
250

251 252 253
					if (isset($add[1])) {
						$cc_addresses[$i] = $add[1];
					}
254
				}
255
			} else {
rjsmelo's avatar
rjsmelo committed
256
				$cc_addresses = [];
257
			}
258

259 260
			$to_addresses = join(',', $to_addresses);
			$cc_addresses = join(',', $cc_addresses);
261

262 263
			if (isset($aux['Reply-To'])) {
				$aux['replyto'] = $aux['Reply-To'];
264

265 266 267
				$aux['replycc'] = $cc_addresses;
			} else {
				$aux['replycc'] = $cc_addresses;
268

269 270
				$aux['replyto'] = $to_addresses;
			}
rjsmelo's avatar
rjsmelo committed
271
			if (! isset($aux['Delivery-Date'])) {
272
				$aux['Delivery-Date'] = $aux['Date'];
273 274
			}
			$aux['timestamp'] = strtotime($aux['Delivery-Date']);
275

276
			// the subject needs to be decoded
277
			$aux['subject'] = isset($aux['Subject']) ? $aux['Subject'] : '';
278 279 280 281
			$aux['from'] = isset($aux['From']) ? utf8_encode($aux['From']) : '';
			$aux['to'] = isset($aux['To']) ? utf8_encode($aux['To']) : '';
			$aux['cc'] = isset($aux['Cc']) ? utf8_encode($aux['Cc']) : '';
			$aux['date'] = isset($aux['Date']) ? utf8_encode($aux['Date']) : '';
282

283
			unset($aux['Subject'], $aux['From'], $aux['To'], $aux['Cc'], $aux['Date'], $aux['Delivery-Date']);
284

285 286 287 288 289
			$smarty->assign('headers', $aux);
		} catch (\Zend\Mail\Protocol\Exception\RuntimeException $e) {
			Feedback::error(tr('Message not found with ID %0', $_REQUEST['msgid']), 'session');
			handleWebmailRedirect('locSection=mailbox&refresh_mail=1');
		} catch (Exception $e) {
rjsmelo's avatar
rjsmelo committed
290 291 292 293
			Feedback::error(
				tr('An error occurred retrieving message ID %0', $_REQUEST['msgid']) . '<br>' . $e->getMessage(),
				'session'
			);
294 295
			handleWebmailRedirect('locSection=mailbox');
		}
rjsmelo's avatar
rjsmelo committed
296
	} else {    // $_REQUEST['msgid'] unset by delete
297
		handleWebmailRedirect('locSection=mailbox');
298
	}
lrargerich's avatar
lrargerich committed
299 300
}

301 302 303 304
///////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// Mailbox ////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////

305
if ($_REQUEST['locSection'] == 'mailbox') {
306
	$current = $webmaillib->get_current_webmail_account($user);
rjsmelo's avatar
rjsmelo committed
307
	if (! $current) {
308
		handleWebmailRedirect('locSection=settings');
309 310
	}

eromneg's avatar
eromneg committed
311
	$autorefresh = $current['autoRefresh'];
312 313 314
	$js = <<< END
function submit_form(msgname,flg)
{
315 316 317
	document.mailb.elements.quickFlag.value= flg;
	document.mailb.elements.quickFlagMsg.value= msgname;
	document.mailb.submit();
318 319
}
END;
320 321

	if ($autorefresh > 0) {
eromneg's avatar
eromneg committed
322
		$js .= 'webmailTimeoutId = window.setTimeout("window.location.reload(true);",$autorefresh*1000);';
323
	}
324
	$headerlib->add_js($js, 0);
325

326
	$h = opendir('temp/mail_attachs/');
327 328 329

	while ($file = readdir($h)) {
		if (substr($file, 0, strlen($user)) == $user) {
330
			@unlink('temp/mail_attachs/' . $file);
331 332 333
		}
	}

334
	closedir($h);
335 336

	$smarty->assign('current', $current);
337 338 339 340 341 342
	$smarty->assign('autoRefresh', $current['autoRefresh']);
	$smarty->assign('imap', $current['imap']);
	$smarty->assign('mbox', $current['mbox']);
	$smarty->assign('maildir', $current['maildir']);
	$smarty->assign('useSSL', $current['useSSL']);
	$smarty->assign('flagsPublic', $current['flagsPublic']);
343

344
	$webmail_reload = isset($_REQUEST['refresh_mail']);
345

346 347 348 349 350 351 352 353
	// connecting with Zend
	try {
		$mail = $webmaillib->get_mail_storage();
	} catch (Exception $e) {
		// do something better with the error
		Feedback::error(tra('There was a problem connecting to that account:') . ' ' . $e->getMessage());
	}

354
	try {
355
		$webmail_list = $webmaillib->refresh_mailbox($user, $current['accountId'], $webmail_reload, $webmaillib->current_account['folder']);
356 357
	} catch (Exception $e) {
		$err = $e->getMessage();
358
		Feedback::error(['mes' => $e->getMessage()], 'session');
rjsmelo's avatar
rjsmelo committed
359
		$urlq = http_build_query(['locSection' => 'settings'], '', '&');
360
		handleWebmailRedirect($urlq);
361
	}
362

363
	// get folder list
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389

	/**
	 * Recurse through the folders to make a flat list for the select options
	 *
	 * @param \Zend\Mail\Storage\Folder $currentFolder   folder object from $mail->getFolders()
	 * @param array                     $output          plain array for the output
	 * @param string                    $delimiter       folder delimiter string (e.g. "/" or ".")
	 */
	function listFolders($currentFolder, & $output, $delimiter) {

		$globalName = $currentFolder->getGlobalName();
		if ( $globalName !== '/') {
			$output[$globalName] = [
				'label' => str_pad('', substr_count($globalName, $delimiter) * 12, '&nbsp;') . $currentFolder->getLocalName(),
				'disabled' => ! $currentFolder->isSelectable(),
			];
		}
		foreach ($currentFolder as $folder) {
			listFolders($folder, $output, $delimiter);
		}
	}

	$foldersSelect = [];
	listFolders($mail->getFolders(), $foldersSelect, $mail->delimiter());

	$smarty->assign('folders', $foldersSelect);
390
	$smarty->assign('currentFolder', $mail->getCurrentFolder());
391

392
	// The user just clicked on one of the flags, so set up for flag change
393
	if (isset($_REQUEST['quickFlagMsg'])) {
394 395
		$realmsg = $_REQUEST['quickFlagMsg'];
		switch ($_REQUEST['quickFlag']) {
396 397
			case 'y':
				$webmaillib->set_mail_flag($current['accountId'], $user, $realmsg, 'isFlagged', 'y');
398
				break;
399

400 401
			case 'n':
				$webmaillib->set_mail_flag($current['accountId'], $user, $realmsg, 'isFlagged', 'n');
402
				break;
403 404 405
		}
	}

406 407
	if (isset($_REQUEST['delete'])) {
		if (isset($_REQUEST['msg'])) {
408
			check_ticket('webmail');
409
			// Now we can delete the messages
410
			$err = '';
411
			foreach ($_REQUEST['msg'] as $msg) {
rjsmelo's avatar
rjsmelo committed
412
				$aux = $webmail_list[$msg - 1];
413 414 415 416 417
				$realmsgid = $aux['realmsgid'];
				try {
					$mail->removeMessage($msg);
					$webmaillib->remove_webmail_message($current['accountId'], $user, $realmsgid);
				} catch (Exception $e) {
rjsmelo's avatar
rjsmelo committed
418
					$err .= $e->getMessage() . ' (' . tra('Mail ID') . ' ' . $msg . ')<br />';
419 420
				}
			}
rjsmelo's avatar
rjsmelo committed
421
			if (! empty($err)) {
422
				Feedback::error(tra('There was a problem while trying to delete these email messages:') . ' ' . $err);
423 424 425 426
			}
		}
	}

rjsmelo's avatar
rjsmelo committed
427
	if (isset($_REQUEST['delete_one'])) {    // currently unused?
428
		check_ticket('webmail');
rjsmelo's avatar
rjsmelo committed
429
		$aux = $webmail_list[$_REQUEST['msgdel'] - 1];
430
		$webmaillib->remove_webmail_message($current['accountId'], $user, $aux['realmsgid']);
431
		try {
432
			$mail->removeMessage($_REQUEST['msgdel']);
433
		} catch (Exception $e) {
rjsmelo's avatar
rjsmelo committed
434 435 436 437
			Feedback::error(
				tra('There was a problem while trying to delete this email message:') . ' '
				. $e->getMessage()
			);
438
		}
439
	}
440 441


442
	if (isset($_REQUEST['delete_one']) || isset($_REQUEST['delete'])) {
443 444
		// Now reopen the mailbox to renumber messages
		try {
rjsmelo's avatar
rjsmelo committed
445 446 447 448 449
			$webmail_list = $webmaillib->refresh_mailbox(
				$user,
				$current['accountId'],
				true
			);    // really need a smarter way of caching the whole mailbox...
450
		} catch (Exception $e) {
451
			Feedback::error(['mes' => $e->getMessage()], 'session');
rjsmelo's avatar
rjsmelo committed
452
			$urlq = http_build_query(['locSection' => 'settings'], '', '&');
453 454
			handleWebmailRedirect($urlq);
		}
455
	}
456
	$mailsum = count($webmail_list);
457

458 459
	if (isset($_REQUEST['operate'])) {
		if (isset($_REQUEST['msg'])) {
460
			check_ticket('webmail');
461
			// Now we can operate the messages
462
			foreach ($_REQUEST['msg'] as $msg) {
rjsmelo's avatar
rjsmelo committed
463
				$aux = $webmail_list[$msg - 1];
464
				$realmsg = $aux['realmsgid'];
465

466
				switch ($_REQUEST['action']) {
467 468
					case 'flag':
						$webmaillib->set_mail_flag($current['accountId'], $user, $realmsg, 'isFlagged', 'y');
469
						break;
470

471 472
					case 'unflag':
						$webmaillib->set_mail_flag($current['accountId'], $user, $realmsg, 'isFlagged', 'n');
473
						break;
474

475 476
					case 'read':
						$webmaillib->set_mail_flag($current['accountId'], $user, $realmsg, 'isRead', 'y');
477
						break;
478

479 480
					case 'unread':
						$webmaillib->set_mail_flag($current['accountId'], $user, $realmsg, 'isRead', 'n');
481
						break;
482 483 484 485 486
				}
			}
		}
	}

487
	$numshow = $current['msgs'];
488

489
	if (isset($_REQUEST['start']) && ($_REQUEST['start'] > $mailsum || empty($_REQUEST['start']))) {
490
		$_REQUEST['start'] = $mailsum;
rjsmelo's avatar
rjsmelo committed
491
	}
492

rjsmelo's avatar
rjsmelo committed
493
	if (! isset($_REQUEST['filter'])) {
494
		$smarty->assign('filter', '');
rjsmelo's avatar
rjsmelo committed
495
	} else {
496
		$smarty->assign('filter', $_REQUEST['filter']);
rjsmelo's avatar
rjsmelo committed
497
	}
498 499

	// If we have a filter then we have to
rjsmelo's avatar
rjsmelo committed
500
	if (! empty($_REQUEST['filter'])) {
501 502
		$tot = 0;

503
		$aux['msgid'] = 'foo';
rjsmelo's avatar
rjsmelo committed
504
		$filtered = [];
505 506
		$filtered[] = $aux;

507
		for ($i = 0; $i < $mailsum; $i++) {
508
			$aux = $webmail_list[$i];
509 510

			// Lets decode the Subject before going to list it... otherwise it returns garbage for non-ascii subjects
511
			$webmaillib->replace_webmail_message($current['accountId'], $user, $aux['realmsgid']);
rjsmelo's avatar
rjsmelo committed
512 513 514
			list(
				$aux['isRead'], $aux['isFlagged'], $aux['isReplied']
				)
515
				= $webmaillib->get_mail_flags($current['accountId'], $user, $aux['realmsgid']);
516

517
			if ($_REQUEST['filter'] == 'unread' && $aux['isRead'] == 'n') {
518 519
				$tot++;
				$filtered[] = $aux;
520
			} elseif ($_REQUEST['filter'] == 'flagged' && $aux['isFlagged'] == 'y') {
521 522 523 524 525 526 527 528
				$tot++;
				$filtered[] = $aux;
			}
		}

		$mailsum = count($filtered) - 1;
	}

rjsmelo's avatar
rjsmelo committed
529
	if (! isset($_REQUEST['start'])) {
530
		$_REQUEST['start'] = $mailsum;
rjsmelo's avatar
rjsmelo committed
531
	}
532

533 534
	$upperlimit = $_REQUEST['start'];
	$smarty->assign('start', $_REQUEST['start']);
rjsmelo's avatar
rjsmelo committed
535
	$webmail_list_page = [];
536

537
	for ($i = $upperlimit, $icount_wlp = count($webmail_list_page); $i > 0 && $icount_wlp < $numshow; $i--) {
rjsmelo's avatar
rjsmelo committed
538
		if (! empty($_REQUEST['filter'])) {
539 540
			$aux = $filtered[$i];
		} else {
rjsmelo's avatar
rjsmelo committed
541
			$aux = $webmail_list[$i - 1];
542
			$webmaillib->replace_webmail_message($current['accountId'], $user, $aux['realmsgid']);
rjsmelo's avatar
rjsmelo committed
543 544 545 546 547
			list($aux['isRead'], $aux['isFlagged'], $aux['isReplied']) = $webmaillib->get_mail_flags(
				$current['accountId'],
				$user,
				$aux['realmsgid']
			);
548
		}
549
		$webmail_list_page[] = $aux;
550 551 552
	}
	$lowerlimit = $i;

rjsmelo's avatar
rjsmelo committed
553
	if ($lowerlimit < 0) {
554
		$lowerlimit = 0;
rjsmelo's avatar
rjsmelo committed
555
	}
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571

	$showstart = $mailsum - $upperlimit + 1;
	$showend = $mailsum - $lowerlimit;
	$smarty->assign('showstart', $showstart);
	$smarty->assign('showend', $showend);
	$smarty->assign('total', $mailsum);

	if ($lowerlimit > 0) {
		$smarty->assign('nextstart', $lowerlimit);
	} else {
		$smarty->assign('nextstart', '');
	}

	if ($upperlimit <> $mailsum) {
		$prevstart = $upperlimit + $numshow;

rjsmelo's avatar
rjsmelo committed
572
		if ($prevstart > $mailsum) {
573
			$prevstart = $mailsum;
rjsmelo's avatar
rjsmelo committed
574
		}
575 576 577 578 579 580

		$smarty->assign('prevstart', $prevstart);
	} else {
		$smarty->assign('prevstart', '');
	}

581
	if ($_REQUEST['start'] <> $mailsum) {
582 583 584 585 586 587 588 589
		$smarty->assign('first', $mailsum);
	} else {
		$smarty->assign('first', '');
	}

	// Now calculate the last message block
	$last = $mailsum % $numshow;

590
	if ($_REQUEST['start'] <> $last) {
591 592 593 594 595
		$smarty->assign('last', $last);
	} else {
		$smarty->assign('last', '');
	}

596
	$smarty->assign('list', $webmail_list_page);
lrargerich's avatar
lrargerich committed
597 598
}

599 600 601 602
///////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// Settings //////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////

603
if ($_REQUEST['locSection'] == 'settings') {
604 605 606 607
	if ($prefs['feature_jquery']) {
		$deleteTitle = tra('Delete');
		$deleteConfirm = tra('Are you sure you want to delete this account?');
		$js = <<< END
608 609

// validate edit/add form
610 611 612
\$('[name=settings]').submit(function() {
	if (!\$('[name=account]').val()) {
		\$('[name=account]').css('background-color', '#fcc').focus();
613 614
		return false;
	}
615 616 617 618 619
	if (!\$('[name=imap]').val() && !\$('[name=pop]').val() && !\$('[name=mbox]').val() && !\$('[name=maildir]').val()) {
		\$('[name=imap]').css('background-color', '#fcc').focus();
		\$('[name=pop]').css('background-color', '#fcc');
		\$('[name=mbox]').css('background-color', '#fcc');
		\$('[name=maildir]').css('background-color', '#fcc');
620 621 622 623
		return false;
	}
});
// set port for imap
624 625
\$('[name=imap]').change(function() {
	if (\$('[name=imap]').val()) {
626
		\$('[name=port]').val(\$('[name=useSSL]').prop('checked')? '993' : '143');
627 628 629
	}
});
// set port for pop
630 631
\$('[name=pop]').change(function() {
	if (\$('[name=pop]').val() && !\$('[name=imap]').val()) {
632
		\$('[name=port]').val(\$('[name=useSSL]').prop('checked')? '995' : '110');
633 634 635
	}
});
// set ports for ssl
636
\$('[name=useSSL]').change(function(v,a) {
637
	if (\$('[name=useSSL]').prop('checked')) {
638 639
		\$('[name=port]').val(\$('[name=imap]').val() ? '993' : '995');
		\$('[name=smtpPort]').val('465');
640
	} else {
641 642
		\$('[name=port]').val(\$('[name=imap]').val() ? '143' : '110');
		\$('[name=smtpPort]').val('25');
643 644 645
	}
});
// confirm deletes
646
\$('a[title=$deleteTitle]').click(function() {
647 648
	return confirm('$deleteConfirm');
});
649 650

END;
651
		$headerlib->add_jq_onready($js);
652
	}
653
	$headerlib->add_js('if (webmailTimeoutId) {window.clearTimeout(webmailTimeoutId);}', 0);
rjsmelo's avatar
rjsmelo committed
654

655
	if (isset($_REQUEST['cancel_acc'])) {
656
		check_ticket('webmail');
rjsmelo's avatar
rjsmelo committed
657
		unset($_REQUEST['cancel_acc']);
658
		unset($_REQUEST['accountId']);
659 660
	}

661
	// The New/Update button was pressed
662
	if (isset($_REQUEST['new_acc'])) {
663
		check_ticket('webmail');
664

665
		if (empty($_REQUEST['accountId'])) {
666
			// Add new account
667
			$_REQUEST['accountId'] = $webmaillib->new_webmail_account(
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
				$user,
				$_REQUEST['account'],
				$_REQUEST['pop'],
				$_REQUEST['port'],
				$_REQUEST['username'],
				$_REQUEST['pass'],
				$_REQUEST['msgs'],
				$_REQUEST['smtp'],
				$_REQUEST['useAuth'],
				$_REQUEST['smtpPort'],
				$_REQUEST['flagsPublic'],
				$_REQUEST['autoRefresh'],
				$_REQUEST['imap'],
				$_REQUEST['mbox'],
				$_REQUEST['maildir'],
				isset($_REQUEST['useSSL']) ? $_REQUEST['useSSL'] : 'n',
				$_REQUEST['fromEmail']
685
			);
686

rjsmelo's avatar
rjsmelo committed
687
			if ($webmaillib->count_webmail_accounts($user) == 1) {    // first account?
688
				$webmaillib->current_webmail_account($user, $_REQUEST['accountId']);
689
			}
690 691
		} else {
			// Update existing account
692
			$webmaillib->replace_webmail_account(
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710
				$_REQUEST['accountId'],
				$user,
				$_REQUEST['account'],
				$_REQUEST['pop'],
				$_REQUEST['port'],
				$_REQUEST['username'],
				$_REQUEST['pass'],
				$_REQUEST['msgs'],
				$_REQUEST['smtp'],
				$_REQUEST['useAuth'],
				$_REQUEST['smtpPort'],
				$_REQUEST['flagsPublic'],
				$_REQUEST['autoRefresh'],
				$_REQUEST['imap'],
				$_REQUEST['mbox'],
				$_REQUEST['maildir'],
				isset($_REQUEST['useSSL']) ? $_REQUEST['useSSL'] : 'n',
				$_REQUEST['fromEmail']
711
			);
712
		}
713 714 715 716 717

		$cat_type = 'webmail account';
		$cat_objid = $_REQUEST['accountId'];
		$cat_name = $_REQUEST['account'];
		$cat_href = 'tiki-webmail.php?locSection=settings&accountId=' . $cat_objid;
rjsmelo's avatar
rjsmelo committed
718
		include_once('categorize.php');
719

720
		unset($_REQUEST['accountId']);
721
	}
722

723
	// The red cross was pressed
724
	if (isset($_REQUEST['remove'])) {
725
		check_ticket('webmail');
726
		$webmaillib->remove_webmail_account($user, $_REQUEST['remove']);
727 728
	}

729 730
	if (isset($_REQUEST['current'])) {
		$webmaillib->current_webmail_account($user, $_REQUEST['current']);
731
		$headerlib->add_js('if (typeof doRefreshWebmail == "function") { doRefreshWebmail(); }');
732 733
	}

734
	$smarty->assign('mailCurrentAccount', $tikilib->get_user_preference($user, 'mailCurrentAccount', 0));
735

736
	$smarty->assign('accountId', empty($_REQUEST['accountId']) ? 0 : $_REQUEST['accountId']);
737
	$smarty->assign('userEmail', trim($userlib->get_user_email($user)));
738

739
	$cat_type = 'webmail account';
rjsmelo's avatar
rjsmelo committed
740 741 742
	$cat_objid = (int)$_REQUEST['accountId'];
	$categories = [];
	include_once('categorize_list.php');
743

rjsmelo's avatar
rjsmelo committed
744
	if (! empty($_REQUEST['accountId'])) {
745
		$info = $webmaillib->get_webmail_account($user, $_REQUEST['accountId']);
746
		$cookietab = 2;
747
	} else {
748 749 750 751 752 753 754 755 756 757 758
		$info['account'] = '';
		$info['username'] = '';
		$info['pass'] = '';
		$info['pop'] = '';
		$info['smtp'] = '';
		$info['useAuth'] = 'n';
		$info['port'] = 110;
		$info['smtpPort'] = 25;
		$info['msgs'] = 20;
		$info['flagsPublic'] = 'n';
		$info['autoRefresh'] = 0;
759 760 761 762
		$info['imap'] = '';
		$info['mbox'] = '';
		$info['maildir'] = '';
		$info['useSSL'] = 'n';
763
		$info['fromEmail'] = '';
764 765 766 767 768
	}

	$smarty->assign('info', $info);
	// List
	$accounts = $webmaillib->list_webmail_accounts($user, 0, -1, 'account_asc', '');
769
	$smarty->assign('accounts', $accounts['data']);
770

771
	$pubAccounts = $webmaillib->list_webmail_group_accounts($user, 0, -1, 'account_asc', '');
rjsmelo's avatar
rjsmelo committed
772
	$accounts = [];
773
	foreach ($pubAccounts['data'] as $acct) {
rjsmelo's avatar
rjsmelo committed
774
		$objectperms = Perms::get(['type' => 'webmail account', 'object' => $acct['accountId']]);
775 776 777 778 779 780 781
		if ($objectperms->use_group_webmail || $objectperms->admin_group_webmail) {
			$accounts[] = $acct;
		}
	}
	$smarty->assign('pubAccounts', $accounts);

	if (isset($_GET['msg'])) {
782
		$smarty->assign('display_msg', $_GET['msg']);
783
	}
lrargerich's avatar
lrargerich committed
784 785
}

786 787 788 789
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// Compose /////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////

790
if ($_REQUEST['locSection'] == 'compose') {
rjsmelo's avatar
rjsmelo committed
791 792
// check if current has been set in the url
	if (isset($_REQUEST['current']) && ! empty($_REQUEST['current'])) {
793 794
		$current = $webmaillib->get_webmail_account($user, $_REQUEST['current']);
	} else {
rjsmelo's avatar
rjsmelo committed
795
		$current = $webmaillib->get_current_webmail_account($user);
796
	}
rjsmelo's avatar
rjsmelo committed
797
// assign accountId and sending email so they are available to the smarty template and
798 799 800
// the accountId can be passed back from template so that different accounts can be used
// 'on the fly' by using a 'current' identifier in the url
	$smarty->assign('curacctId', $current['accountId']);
801
// check if current fromEmail is not set and use login email instead
rjsmelo's avatar
rjsmelo committed
802
	if ($current['fromEmail'] != '') {
803 804 805 806
		$smarty->assign('sendFrom', $current['fromEmail']);
	} else {
		$smarty->assign('sendFrom', trim($userlib->get_user_email($user)));
	}
807

rjsmelo's avatar
rjsmelo committed
808
	if (! $current) {
809
		handleWebmailRedirect('locSection=settings');
810
	}
811
	$headerlib->add_js('if (webmailTimeoutId) {window.clearTimeout(webmailTimeoutId);}', 0);
812

813
	// Send a message
814
	if (isset($_REQUEST['reply']) || isset($_REQUEST['replyall'])) {
815
		check_ticket('webmail');
816
		$webmaillib->set_mail_flag($current['accountId'], $user, $_REQUEST['realmsgid'], 'isReplied', 'y');
817 818 819 820 821
	}

	$smarty->assign('sent', 'n');
	$smarty->assign('attaching', 'n');

822
	if (isset($_REQUEST['send'])) {
823 824
		$email = empty($current['fromEmail']) ? $userlib->get_user_email($user) : $current['fromEmail'];
		$mail = new TikiMail($user, $email);
825

rjsmelo's avatar
rjsmelo committed
826
		if (! empty($_REQUEST['cc'])) {
827
			$mail->setCc($_REQUEST['cc']);
828
		}
rjsmelo's avatar
rjsmelo committed
829
		if (! empty($_REQUEST['bcc'])) {
830
			$mail->setBcc($_REQUEST['bcc']);
831
		}
832
		$mail->setSubject($_REQUEST['subject']);
833

834
		if ($_REQUEST['attach1']) {
835
			check_ticket('webmail');
836
			$a1 = file_get_contents('temp/mail_attachs/' . $_REQUEST['attach1file']);
837

838
			$mail->addAttachment($a1, $_REQUEST['attach1'], $_REQUEST['attach1type']);
839
			@unlink('temp/mail_attachs/' . $_REQUEST['attach1file']);
840 841
		}

842
		if ($_REQUEST['attach2']) {
843
			check_ticket('webmail');
844
			$a2 = file_get_contents('temp/mail_attachs/' . $_REQUEST['attach2file']);
845

846
			$mail->addAttachment($a2, $_REQUEST['attach2'], $_REQUEST['attach2type']);
847
			@unlink('temp/mail_attachs/' . $_REQUEST['attach2file']);
848 849
		}

850
		if ($_REQUEST['attach3']) {
851
			check_ticket('webmail');
852
			$a3 = file_get_contents('temp/mail_attachs/' . $_REQUEST['attach3file']);
853

854
			$mail->addAttachment($a3, $_REQUEST['attach3'], $_REQUEST['attach3type']);
855
			@unlink('temp/mail_attachs/' . $_REQUEST['attach3file']);
856
		}
rjsmelo's avatar
rjsmelo committed
857 858

		if ($_REQUEST['fattId']) {
859 860
			$filegallib = TikiLib::lib('filegal');
			$filedata = $filegallib->get_file_info($_REQUEST['fattId']);
rjsmelo's avatar
rjsmelo committed
861 862
			$a4 = file_get_contents($prefs['fgal_use_dir'] . $filedata['path']);

863
			$mail->addAttachment($a4, $filedata['filename'], $filedata['filetype']);
rjsmelo's avatar
rjsmelo committed
864
		}
865

rjsmelo's avatar
rjsmelo committed
866
		if ($_REQUEST['fattId']) {
867 868
			$filegallib = TikiLib::lib('filegal');
			$filedata = $filegallib->get_file_info($_REQUEST['fattId']);
rjsmelo's avatar
rjsmelo committed
869 870
			$a4 = file_get_contents($prefs['fgal_use_dir'] . $filedata['path']);

871
			$mail->addAttachment($a4, $filedata['filename'], $filedata['filetype']);
rjsmelo's avatar
rjsmelo committed
872
		}
873

rjsmelo's avatar
rjsmelo committed
874
		//	$mail->setSMTPParams($current['smtp'], $current['smtpPort'], '', $current['useAuth'], $current['username'], $current['pass']);   // commented out as a temporary fix - might need to do more later
875

876 877
		if (isset($_REQUEST['useHTML']) && $_REQUEST['useHTML'] == 'on') {
			$mail->setHTML($_REQUEST['body'], strip_tags($_REQUEST['body']));
878
		} else {
879
			$mail->setText($_REQUEST['body']);
880 881
		}

882
		$to_array_1 = preg_split('/[, ;]/', $_REQUEST['to']);
rjsmelo's avatar
rjsmelo committed
883
		$to_array = [];
884 885

		foreach ($to_array_1 as $to_1) {
rjsmelo's avatar
rjsmelo committed
886
			if (! empty($to_1)) {
887 888 889 890
				$to_array[] = $to_1;
			}
		}

891
		$to_array = $contactlib->parse_nicknames($to_array);
892 893

		// Get email addresses not in the address book
sylvieg's avatar
sylvieg committed
894
		$not_contacts = $contactlib->are_contacts($to_array, $user);
895 896 897 898 899 900 901 902 903

		if (count($not_contacts) > 0) {
			$smarty->assign('notcon', 'y');
		} else {
			$smarty->assign('notcon', 'n');
		}

		$smarty->assign('not_contacts', $not_contacts);

904
		if ($mail->send($to_array, 'smtp')) {
rjsmelo's avatar
rjsmelo committed
905
			$msg = tra('Your email was sent');
906
		} else {
luciash's avatar
luciash committed
907
			if (is_array($mail->errors)) {
908
				$msg = '';
909
				$temp_max = count($mail->errors);
rjsmelo's avatar
rjsmelo committed
910 911
				for ($i = 0; $i < $temp_max; $i++) {
					$msg .= $mail->errors[$i] . '<br />';
luciash's avatar
luciash committed
912 913
				}
			} else {
rjsmelo's avatar
rjsmelo committed
914
				$msg = $mail->errors;
luciash's avatar
luciash committed
915
			}
916 917 918 919 920 921
		}

		$smarty->assign('sent', 'y');
		$smarty->assign('msg', $msg);
	}

922
	if (isset($_REQUEST['attach'])) {
923 924 925
		$smarty->assign('attaching', 'y');
	}

926
	if (isset($_REQUEST['remove_attach1'])) {
927
		check_ticket('webmail');
928
		@unlink($_REQUEST['attach1file']);
929

930 931 932
		$_REQUEST['attach1'] = '';
		$_REQUEST['attach1file'] = '';
		$_REQUEST['attach1type'] = '';
933 934
	}

935
	if (isset($_REQUEST['remove_attach2'])) {
936
		check_ticket('webmail');
937
		@unlink($_REQUEST['attach2file']);
938

939 940 941
		$_REQUEST['attach2'] = '';
		$_REQUEST['attach2file'] = '';
		$_REQUEST['attach2type'] = '';
942 943
	}

944
	if (isset($_REQUEST['remove_attach3'])) {
945
		check_ticket('webmail');
946
		@unlink($_REQUEST['attach3file']);
947

948 949 950
		$_REQUEST['attach3'] = '';
		$_REQUEST['attach3file'] = '';
		$_REQUEST['attach3type'] = '';
951 952
	}

953
	if (isset($_REQUEST['attached'])) {
954 955
		// Now process the uploads
		if (isset($_FILES['userfile1']) && is_uploaded_file($_FILES['userfile1']['tmp_name'])) {
956
			check_ticket('webmail');
957 958 959 960 961 962
			$size = $_FILES['userfile1']['size'];

			if ($size < 1500000) {
				$name = $_FILES['userfile1']['name'];

				$type = $_FILES['userfile1']['type'];
963 964 965 966
				$_REQUEST['attach1file'] = $user . md5($webmaillib->genPass());
				$_REQUEST['attach1type'] = $type;
				$_REQUEST['attach1'] = $name;
				move_uploaded_file($_FILES['userfile1']['tmp_name'], 'temp/mail_attachs/' . $_REQUEST['attach1file']);
967 968 969 970
			}
		}

		if (isset($_FILES['userfile2']) && is_uploaded_file($_FILES['userfile2']['tmp_name'])) {
971
			check_ticket('webmail');
972 973 974 975 976 977
			$size = $_FILES['userfile2']['size'];

			if ($size < 1500000) {
				$name = $_FILES['userfile2']['name'];

				$type = $_FILES['userfile2']['type'];
978 979 980 981
				$_REQUEST['attach2file'] = $user . md5($webmaillib->genPass());
				$_REQUEST['attach2type'] = $type;
				$_REQUEST['attach2'] = $name;
				move_uploaded_file($_FILES['userfile2']['tmp_name'], 'temp/mail_attachs/' . $_REQUEST['attach2file']);
982 983 984 985
			}
		}

		if (isset($_FILES['userfile3']) && is_uploaded_file($_FILES['userfile3']['tmp_name'])) {
986
			check_ticket('webmail');
987 988 989 990 991 992
			$size = $_FILES['userfile3']['size'];

			if ($size < 1500000) {
				$name = $_FILES['userfile3']['name'];

				$type = $_FILES['userfile3']['type'];
993 994 995 996
				$_REQUEST['attach3file'] = $user . md5($webmaillib->genPass());
				$_REQUEST['attach3type'] = $type;
				$_REQUEST['attach3'] = $name;
				move_uploaded_file($_FILES['userfile3']['tmp_name'], 'temp/mail_attachs/' . $_REQUEST['attach3file']);
997 998 999 1000 1001
			}
		}
	}

	// Build the to array
rjsmelo's avatar
rjsmelo committed
1002
	if (! isset($_REQUEST['attach1'])) {
1003
		$_REQUEST['attach1'] = '';
rjsmelo's avatar
rjsmelo committed
1004
	}
1005

rjsmelo's avatar
rjsmelo committed
1006
	if (! isset($_REQUEST['attach2'])) {
1007
		$_REQUEST['attach2'] = '';
rjsmelo's avatar
rjsmelo committed
1008
	}
1009

rjsmelo's avatar
rjsmelo committed
1010
	if (! isset($_REQUEST['attach3'])) {
1011
		$_REQUEST['attach3'] = '';
rjsmelo's avatar
rjsmelo committed
1012
	}