YaWK  24.1
Yet another WebKit
webmail.php
Go to the documentation of this file.
1 <?php
2 // include imap client classes
3 require_once "../system/engines/imapClient/AdapterForOutgoingMessage.php";
4 require_once "../system/engines/imapClient/Helper.php";
5 require_once "../system/engines/imapClient/ImapClient.php";
6 require_once "../system/engines/imapClient/ImapClientException.php";
7 require_once "../system/engines/imapClient/ImapConnect.php";
8 require_once "../system/engines/imapClient/IncomingMessage.php";
9 require_once "../system/engines/imapClient/IncomingMessageAttachment.php";
10 require_once "../system/engines/imapClient/OutgoingMessage.php";
11 require_once "../system/engines/imapClient/Section.php";
12 require_once "../system/engines/imapClient/SubtypeBody.php";
13 require_once "../system/engines/imapClient/TypeAttachments.php";
14 require_once "../system/engines/imapClient/TypeBody.php";
15 
16 // let php know we need these classes:
17 use SSilence\ImapClient\ImapClientException;
18 use SSilence\ImapClient\ImapClient as Imap;
19 
20 use YAWK\alert;
21 use YAWK\backend;
22 use YAWK\db;
23 use YAWK\language;
24 use YAWK\settings;
25 use YAWK\webmail;
26 
27 /** @var $db db */
28 /** @var $lang language */
29 
30 // get all webmail setting values into an array
31 $webmailSettings = settings::getValueSettingsArray($db, "webmail_");
32 
33 // imap connection only made be made if webmail is set to active
34 // check if webmail is activated
35 if ($webmailSettings['webmail_active'] == true)
36 { // webmail enabled, get mailbox settings
37 
38  // mailbox server (imap.server.tld)
39  $server = $webmailSettings['webmail_imap_server'];
40  // mailbox user ([email protected])
41  $username = $webmailSettings['webmail_imap_username'];
42  // mailbox password
43  $password = $webmailSettings['webmail_imap_password'];
44  // encryption type (ssl, tsl, null)
45  $encryption = "/" . $webmailSettings['webmail_imap_encrypt'];
46  // port (default: 993)
47  $port = ":" . $webmailSettings['webmail_imap_port'];
48  // start at email no
49  $imapStart = $webmailSettings['webmail_imap_start'];
50  // amount of emails to be retrieved
51  $imapAmount = $webmailSettings['webmail_imap_amount'];
52  // amount of emails to be retrieved
53  $imapMsgTypes = $webmailSettings['webmail_imap_msgtypes'];
54  // sortation asc | desc
55  $imapSortation = $webmailSettings['webmail_imap_sortation'];
56  // novalidate-cert
57  $novalidate = $webmailSettings['webmail_imap_novalidate'];
58 
59  // include webmail class
60  require_once "../system/classes/webmail.php";
61  // create new webmail object
62  $webmail = new webmail();
63  // set connection info var
64  $webmail->connectionInfo = "<i>$username</i>";
65 
66  $options = array($novalidate);
67 
68  try // open connection to imap server
69  {
70  // create new imap handle
71  $imap = new Imap($server.$port.$encryption, $username, $password, $encryption, 0, 0, $options);
72  // connection successful, error = false
73  $error = false;
74  $errorMsg = '';
75 
76  // webmail page called with parameter - user requested a folder
77  if (isset($_GET['folder']) && (!empty($_GET['folder']) && (is_string($_GET['folder']))))
78  { // select requested folder
79  $imap->selectFolder($_GET['folder']);
80  // set current folder string
81  $imap->currentFolder = $_GET['folder'];
82  }
83  else // webmail page called w/o any parameters
84  { // select default folder
85  $imap->selectFolder('INBOX');
86  $imap->currentFolder = "INBOX";
87  }
88  }
89  // open imap connection failed...
90  catch (ImapClientException $error)
91  { // no errors in production...
92  $webmail->connectionInfo = $error->getMessage() . PHP_EOL;
93  // exit with error
94  $error = true;
95  $errorMsg = 'Oh no! Verbindung mit server: '.$server.' als user: '.$username.' nicht moeglich!';
96  $imap = NULL;
97  }
98 
99 
100  // DELETE ACTION: delete single message
101  if (isset($_GET['deleteMessage']) && ($_GET['deleteMessage'] == true))
102  { // delete message
103  if ($webmail->deleteMessage($imap, $_GET['folder'], $_GET['uid']))
104  { // email deleted
105  alert::draw("success", "Email deleted", "The email was deleted", "", 1200);
106  }
107  else
108  { // failed to delete email
109  alert::draw("danger", "ERROR:", "Unable to delete email", "", 2800);
110  }
111  }
112 
113  // PURGE FOLDER: delete all messages in this folder
114  if (isset($_GET['purgeTrash']) && ($_GET['purgeTrash'] == true))
115  { // purge folder
116  $imap->selectFolder("Trash");
117  if ($webmail->purgeTrash($imap))
118  { // email deleted
119  alert::draw("success", "Mailbox cleaned", "The trash and spam folders were cleaned up", "", 1200);
120  }
121  else
122  { // failed to delete email
123  alert::draw("danger", "ERROR:", "Unable to purge trash and spam folder", "", 2800);
124  }
125  }
126 }
127 else // webmail is not activated...
128  { // leave vars empty
129  $webmail = "";
130  $imap = "";
135  $error = "";
136  $errorMsg = "";
137  }
138 ?>
139 <!-- JS: load data tables -->
140 <script type="text/javascript">
141  $(document).ready(function() {
142  $('#table-sort').dataTable({
143  "bPaginate": false,
144  "bLengthChange": false,
145  "bFilter": true,
146  "bSort": true,
147  "bInfo": true,
148  "bAutoWidth": false
149  });
150 
151  });
152 
153  // make whole table row clickable
154  $('#table-sort tr').click(function() {
155  var href = $(this).find("a").attr("href");
156  if(href) {
157  window.location = href;
158  }
159  });
160 
161 
162  /**
163  * Mark specific email as seen / unseen.
164  * @param msgno the affected message number
165  * @param state setSeen|setUnseen
166  */
167  function markAsSeen(msgno, state){
168  $.ajax({
169  type: "POST",
170  url: 'js/webmail-markAsSeen.php',
171  data: {msgno: msgno, state:state},
172  success: function(data){
173  // alert(data);
174 
175  // envelope icon element
176  let seenIcon = $('#seenIcon_'+msgno);
177  let seenIconLink = $('#seenIconLink_'+msgno);
178  let mailboxName = $('#mailboxName_'+msgno);
179  let mailboxSubject = $('#mailboxSubject_'+msgno);
180  let newMessagesLabel = $('#newMessagesLabel');
181  // get value from new message label, remove first 2 chars (+&nbsp;)
182  let labelCount = $(newMessagesLabel).text().slice(2);
183 
184  // the email icon in the top navbar
185  let envelopeLabel = $('#envelope-label');
186 
187  // remove icon class
188  $(seenIcon).removeClass();
189 
190  // state setSeen requested
191  if (state === 'setSeen')
192  { // set html markup for seen message (light text)
193  $(seenIcon).addClass('fa fa-envelope-open-o text-muted');
194  $(mailboxName).removeClass().addClass('mailbox-name');
195  $(mailboxSubject).removeClass().addClass('mailbox-subject');
196  // change function call to make it toggle correctly
197  $(seenIconLink).attr("onclick",'markAsSeen('+msgno+', \'setUnseen\')');
198 
199  // update new messages label value
200  // if there are more mails than 0
201  if (labelCount > 1)
202  {
203  // subtract 1 from label counter
204  labelCount--;
205  // update new mails label counter
206  $(newMessagesLabel).text('+ '+labelCount);
207  // set navbar icon
208  $(envelopeLabel).text(labelCount);
209  }
210  else
211  { // no more new mails - fade out label
212  $(newMessagesLabel).text('+ 0');
213  $(newMessagesLabel).fadeOut();
214  $(envelopeLabel).fadeOut();
215  }
216  }
217  else
218  { // set html markup for unseen message (bold text)
219  $(seenIcon).addClass('fa fa-envelope text-muted');
220  $(mailboxName).removeClass().addClass('mailbox-name text-bold');
221  $(mailboxSubject).removeClass().addClass('mailbox-subject text-bold');
222  // change function call to make it toggle correctly
223  $(seenIconLink).attr("onclick",'markAsSeen('+msgno+', \'setSeen\')');
224 
225  // if there are more mails than 0
226  if (labelCount > 0)
227  { // subtract 1 from label counter
228  labelCount++;
229  // update new mails label counter
230  $(newMessagesLabel).text('+ '+labelCount);
231  $(envelopeLabel).text(labelCount);
232  console.log('LABEL COUNTER:' +labelCount);
233  }
234  else
235  { // no more new mails - fade out label
236  $(newMessagesLabel).text('+ 1');
237  $(envelopeLabel).fadeIn();
238  $(newMessagesLabel).fadeIn();
239  }
240  }
241  }
242  });
243  }
244 
245  /**
246  * Mark specific email as flagged (mark as important with star)
247  * @param uid the affected mail uid
248  * @param state setSeen|setUnseen
249  */
250  function markAsFlagged(uid, state){
251  // alert('mark as unread clicked for uid '+uid+'');
252  $.ajax({
253  type: "POST",
254  url: 'js/webmail-setFlagged.php',
255  data: {uid: uid, state:state},
256  success: function(data){
257  // alert(data);
258 
259  // envelope icon element
260  let starIcon = $('#starIcon_'+uid);
261  let starIconLink = $('#starIconLink_'+uid);
262 
263  // remove icon class
264  $(starIcon).removeClass();
265 
266  // state setFlagged
267  if (state === 'setFlagged')
268  { // set html markup for flagged message (light text)
269  $(starIcon).addClass('fa fa-star text-orange');
270  // change function call to make it toggle correctly
271  $(starIconLink).attr("onclick",'markAsFlagged('+uid+', \'setUnFlagged\')');
272  }
273 
274  // state setFlagged
275  else if (state === 'setUnFlagged')
276  { // set html markup for flagged message (light text)
277  $(starIcon).addClass('fa fa-star-o text-orange');
278  // change function call to make it toggle correctly
279  $(starIconLink).attr("onclick",'markAsFlagged('+uid+', \'setFlagged\')');
280  }
281  }
282  });
283  }
284 
285  /**
286  * Move a specific email (uid) from folder to targetFolder
287  * @param uid the affected mail uid
288  * @param folder source folder
289  * @param targetFolder target folder
290  */
291  function moveMessage(uid, folder, targetFolder){
292  $.ajax({
293  type: "POST",
294  url: 'js/webmail-moveMessage.php',
295  data: {uid: uid, folder:folder, targetFolder:targetFolder},
296  success: function(data){
297  // alert(data);
298 
299  // set html element vars
300  let emailRow = $('#emailRow_'+uid);
301  // update message count (beside folder overview)
302  let messageCountSourceElement = $('#messageCount_'+folder+' small');
303  let messageCountSource = $(messageCountSourceElement).text().slice(1,-1);
304  let messageCountTargetElement = $('#messageCount_'+targetFolder+' small');
305  let messageCountTarget = $(messageCountTargetElement).text().slice(1,-1);
306  // subtract -1 from message count source folder
307  messageCountSource--;
308  // add +1 to message count target folder
309  messageCountTarget++;
310  // re-write message source count to element
311  $(messageCountSourceElement).text('('+messageCountSource+')');
312  // re-write message target count to element
313  $(messageCountTargetElement).text('('+messageCountTarget+')');
314 
315  // fadeOut table row that contains moved email
316  $(emailRow).removeClass().addClass('animated fadeOutRight');
317  $(emailRow).fadeOut();
318  }
319  });
320  }
321 
322  /**
323  * Delete a specific message (finally)
324  * @param uid the affected message uid number
325  * @param folder the current folder
326  */
327  function deleteMessage(uid, folder){
328  $.ajax({
329  type: "POST",
330  url: 'js/webmail-deleteMessage.php',
331  data: {uid:uid, folder:folder},
332  success: function(data){
333  // alert(data);
334  // envelope icon element
335  var newMessagesLabel = $('#newMessagesLabel');
336  // get value from new message label, remove first 2 chars (+&nbsp;)
337  var labelCount = $(newMessagesLabel).text().slice(2);
338  // the email icon in the top navbar
339  var envelopeLabel = $('#envelope-label');
340  // the current email row
341  var emailRow = $('#emailRow_'+uid);
342 
343  // update message count (beside folder overview)
344  var messageCountElement = $('#messageCount_'+folder+' small');
345  var messageCount = $(messageCountElement).text().slice(1,-1);
346  // subtract -1 from message count
347  messageCount--;
348  // re-write message count to element
349  $(messageCountElement).text('('+messageCount+')');
350 
351  // slide + fadeOut affected email table row
352  $(emailRow).removeClass().addClass('animated fadeOutRight');
353  $(emailRow).fadeOut();
354 
355  // update new messages label value
356  // if there are more mails than 0
357  if (labelCount > 1)
358  {
359  // subtract 1 from label counter
360  labelCount--;
361  // update new mails label counter
362  $(newMessagesLabel).text('+ '+labelCount);
363  // set navbar icon
364  $(envelopeLabel).text(labelCount);
365  }
366  else
367  { // no more new mails - fade out label
368  $(newMessagesLabel).text('+ 0');
369  $(newMessagesLabel).fadeOut();
370  $(envelopeLabel).fadeOut();
371  }
372  }
373  });
374  }
375 </script>
376 
377 <?php
378 // TEMPLATE WRAPPER - HEADER & breadcrumbs
379 echo "
380  <!-- Content Wrapper. Contains page content -->
381  <div class=\"content-wrapper\" id=\"content-FX\">
382  <!-- Content Header (Page header) -->
383  <section class=\"content-header\">";
384 /* draw Title on top */
385 echo backend::getTitle($lang['WEBMAIL'], $lang['WEBMAIL_SUBTEXT']);
386 echo"<ol class=\"breadcrumb\">
387  <li><a href=\"index.php\" title=\"$lang[DASHBOARD]\"><i class=\"fa fa-dashboard\"></i> $lang[DASHBOARD]</a></li>
388  <li class=\"active\"><a href=\"index.php?page=webmail\" title=\"$lang[WEBMAIL]\"> $lang[WEBMAIL]</a></li>
389  </ol>
390  </section>
391  <!-- Main content -->
392  <section class=\"content\">";
393 /* page content start here */
394 // check if there was a connection error
395 if (isset($error) && ($error == true))
396 { // output error message
397  echo $errorMsg;
398 }
399 // draw webmail only, of webmal is set to active...
400 if ($webmailSettings['webmail_active'] == true && ($error == false))
401 {
402 ?>
403 <div class="row">
404  <div class="col-md-3">
405  <!-- left col -->
406  <a href="index.php?page=webmail-compose" class="btn btn-success btn-large" style="width: 100%;">Write a message</a><br><br>
407  <div class="box box-default animated fadeIn">
408  <div class="box-header with-border">
409  <h3 class="box-title">Folders</h3>
410 
411  <div class="box-tools">
412  <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
413  </button>
414  </div>
415  </div>
416  <div class="box-body no-padding" style="">
417  <ul class="nav nav-pills nav-stacked">
418  <?php
419  /** @var $imap \SSilence\ImapClient\ImapClient */
420  $webmail->drawFolders($imap, $imap->getFolders());
421  ?>
422  </ul>
423  </div>
424  <!-- /.box-body -->
425  </div>
426  </div> <!-- /. left col -->
427 
428  <div class="col-md-9 animated fadeIn">
429  <!-- right col -->
430  <div class="box box-secondary">
431  <div class="box-header with-border">
432  <h3 class="box-title"><?php echo $imap->currentFolder; ?> </h3>
433  <?php echo "<small>".$webmail->connectionInfo."</small>"; ?>
434  <!-- search box -->
435  <div class="box-tools pull-right">
436  <div class="has-feedback">
437  <input type="text" class="form-control input-sm" placeholder="Deep Search">
438  <span class="glyphicon glyphicon-search form-control-feedback"></span>
439  </div>
440  </div>
441  <!-- /.box-tools -->
442  </div>
443  <!-- /.box-header -->
444  <div class="box-body no-padding">
445  <div class="mailbox-controls">
446  <?php $webmail->drawMailboxControls($imap, "inbox", 0, $imap->currentFolder, $lang); ?>
447  </div>
448  <div class="table-responsive mailbox-messages">
449  <table class="table table-striped table-hover table-responsive" id="table-sort">
450  <thead>
451  <tr>
452  <td><div class="icheckbox_flat-blue" aria-checked="false" aria-disabled="false" style="position: relative; width: 100%"><input type="checkbox" style="position: absolute; opacity: 0;"><ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; background: rgb(255, 255, 255); border: 0px; opacity: 0;"></ins></div></td>
453  <td class="mailbox-star"></td>
454  <td class="mailbox-star"></td>
455  <td class="mailbox-name"><?php echo $lang['SENDER_FROM']; ?></td>
456  <td class="mailbox-subject"><?php echo $lang['SUBJECT']; ?></td>
457  <td class="mailbox-attachment"></td>
458  <td class="mailbox-date"><?php echo $lang['DATE']; ?></td>
459  <td class="mailbox-star"></td>
460  </tr>
461  </thead>
462  <tbody>
463  <?php
464  $emails = array();
465  // CURRENT:
466  $imap->selectFolder($imap->currentFolder);
467  $emails = $imap->getMessages($imapAmount, $imapStart, $imapSortation, $imapMsgTypes);
468  $webmail->drawHeaders($emails, $imap->currentFolder, $lang);
469  ?>
470  </tbody>
471  </table>
472  <!-- /.table -->
473  </div>
474  <!-- /.mail-box-messages -->
475  </div>
476  <!-- /.box-body -->
477  <div class="box-footer no-padding">
478  <?php $webmail->drawMailboxControls($imap, "inbox", 0, $imap->currentFolder, $lang); ?>
479  </div>
480  </div> <!-- /. box secondary -->
481  </div> <!-- /. right col -->
482 </div> <!-- /. row -->
483 <?php
484  // close current imap connection
485  $imap->close();
486 }
487 else
488  { // webmail not enabled
489  echo "<h4>".$lang['WEBMAIL_NOT_ENABLED']."</h4>";
490  }
491 ?>
print $lang['FILEMAN_UPLOAD']
$imapMsgTypes
Definition: webmail.php:134
$errorMsg
Definition: webmail.php:136
$imapStart
Definition: webmail.php:131
$imapAmount
Definition: webmail.php:133
$imapSortation
Definition: webmail.php:132
$imap
Definition: webmail.php:130
$webmailSettings
Definition: webmail.php:31
$error
Definition: webmail.php:135
Throws a fancy Bootstrap Alert (success, info, warning or danger)
Definition: alert.php:19
Backend class serves a few useful functions for the admin backend.
Definition: backend.php:27
Mysqli database class; returns db connection object.
Definition: db.php:16
The language class - support multilingual backend.
Definition: language.php:17
Settings class: get and set YaWK system settings.
Definition: settings.php:9
Integrated IMAP Webmail.
Definition: webmail.php:25
$server
Definition: email-send.php:133
function window
Definition: fuckAdBlock.js:8
function a
Definition: browser.js:14
type
Definition: menu-new.php:35
print $_GET['id']
Definition: page-edit.php:357
function i(e, t)
Definition: plyr.js:1
document ready(function() { $('a[data-confirm]').click(function(ev) { modal='#dataConfirmModal';var href=$(this).attr('href');var title=$(this).attr('title');var icon=$(this).attr('data-icon');if(!icon) { icon='fa fa-trash-o';} if(!$(modal).length) { $('body').append('< div id="dataConfirmModal" class="modal fade" role="dialog" aria-labelledby="dataConfirmLabel" aria-hidden="true">< div class="modal-dialog">< div class="modal-content">< div class="modal-header">< button type="button" class="close" data-dismiss="modal" aria-hidden="true">< i class="fa fa-times"></i ></button >< br >< div class="col-md-1">< h3 class="modal-title">< i class="'+icon+'"></i ></h3 ></div >< div class="col-md-11">< h3 class="modal-title" id="dataConfirmLabel">'+title+'</h3 ></div ></h3 ></div >< div class="modal-body"></div >< div class="modal-footer">< button type="button" class="btn btn-default" data-dismiss="modal" aria-hidden="true">Abbrechen</button >< a type="button" class="btn btn-danger" id="dataConfirmOK">< i class="'+icon+'"></i > L &ouml;schen</a ></div ></div ></div ></div >');} $(modal).find('.modal-body').text($(this).attr('data-confirm'));$('#dataConfirmOK').attr('href', href);$(modal).modal({show:true});return false;});$('#terminateUser').click(function() { var terminate=window.confirm("ACHTUNG!\nDas wird Deinen Account permanent deaktivieren.\n"+"Bist Du Dir sicher, dass Du das tun willst?");if(terminate===true) { var terminateUser=window.confirm("Bist Du Dir wirklich ganz sicher?\n"+"Diese Aktion kann nicht rueckgaengig gemacht werden.");if(terminateUser===true) { $.get('system/templates/YaWK-bootstrap3/js/terminate-user.php', function(data) { if(data==="true") { setTimeout("window.location='logout.html'", 0);} else { alert("Fehler: "+data);} });} } });function dismissNotifications() { $.ajax({ url:'js/dismiss-notifications.php', type:'POST', success:function(data) { if(!data) { alert('Something went wrong!');return false;} } });$("#bell-label").fadeOut();$('#notification-header').html('You have 0 notifications');$('#notification-menu').fadeOut();} $("#dismiss").click(function() { dismissNotifications();});function disableButtons(delay) { $('#loginButton').removeClass().addClass('btn btn-success disabled').attr('id', 'LOGIN_FORBIDDEN');$('#resetPasswordButton').removeClass().addClass('btn btn-danger disabled');setTimeout(function() { $('#LOGIN_FORBIDDEN').attr('id', 'loginButton').removeClass().addClass('btn btn-success');$('#resetPasswordButton').removeClass().addClass('btn btn-danger');}, delay);} $("#loginButton").click(function(){ if($('#loginButton').length > 0) { if($('#loginButton').hasClass('btn') &&$('#loginButton').hasClass('btn-success') &&$('#loginButton').hasClass('disabled')) { } else { $("#loginForm").submit();disableButtons(10000);} } else if($('#LOGIN_FORBIDDEN').length > 0) { if($('#LOGIN_FORBIDDEN').hasClass('btn') &&$('#LOGIN_FORBIDDEN').hasClass('btn-success') &&$('#LOGIN_FORBIDDEN').hasClass('disabled')) { } else { } } });$("#blockedBtn").hover(function() { $("#blockedBtn").hide();$("#askBtn").fadeIn(820);});})