} } if (count($list_backends) > 1) { $abook_selection = addSelect('new_bnum', $list_backends, $current_backend, true) . addSubmit(_("Change"), 'change_abook'); } } $defdata = array(); $formerror = ''; $abortform = false; $showaddrlist = true; $defselected = array(); $form_url = 'addressbook.php'; /* Handle user's actions */ if (sqgetGlobalVar('REQUEST_METHOD', $req_method, SQ_SERVER) && $req_method == 'POST') { // first, validate security token sm_validate_security_token($submitted_token, -1, TRUE); /************************************************** * Add new address * **************************************************/ if (isset($addaddr)) { if (isset($backend)) { $r = $abook->add($addaddr, $backend); } else { $r = $abook->add($addaddr, $abook->localbackend); } /* Handle error messages */ if (!$r) { /* Remove backend name from error string */ $errstr = $abook->error; $errstr = preg_replace('/^\\[.*\\] */', '', $errstr); $formerror = $errstr;
/** * Process messages list form and handle the cache gracefully. If $sButton and * $aUid are provided as argument then you can fake a message list submit and * use it i.e. in read_body.php for del move next and update the cache * * @param resource $imapConnection imap connection * @param array $aMailbox (reference) cached mailbox * @param string $sButton fake a submit button * @param array $aUid fake the $msg array * @param string $targetMailbox fake the target mailbox for move operations * @param boolean $bypass_trash fake the bypass trash checkbox for delete operations * @return string $sError error string in case of an error * @since 1.5.1 * @author Marc Groot Koerkamp */ function handleMessageListForm($imapConnection, &$aMailbox, $sButton = '', $aUid = array(), $targetMailbox = '', $bypass_trash = NULL) { /* incoming formdata */ $sButton = sqgetGlobalVar('moveButton', $sTmp, SQ_FORM) ? 'move' : $sButton; $sButton = sqgetGlobalVar('copyButton', $sTmp, SQ_FORM) ? 'copy' : $sButton; $sButton = sqgetGlobalVar('expungeButton', $sTmp, SQ_FORM) ? 'expunge' : $sButton; $sButton = sqgetGlobalVar('forward', $sTmp, SQ_FORM) ? 'forward' : $sButton; $sButton = sqgetGlobalVar('delete', $sTmp, SQ_FORM) ? 'setDeleted' : $sButton; $sButton = sqgetGlobalVar('undeleteButton', $sTmp, SQ_FORM) ? 'unsetDeleted' : $sButton; $sButton = sqgetGlobalVar('markRead', $sTmp, SQ_FORM) ? 'setSeen' : $sButton; $sButton = sqgetGlobalVar('markUnread', $sTmp, SQ_FORM) ? 'unsetSeen' : $sButton; $sButton = sqgetGlobalVar('markFlagged', $sTmp, SQ_FORM) ? 'setFlagged' : $sButton; $sButton = sqgetGlobalVar('markUnflagged', $sTmp, SQ_FORM) ? 'unsetFlagged' : $sButton; if (empty($targetMailbox)) { sqgetGlobalVar('targetMailbox', $targetMailbox, SQ_FORM); } if (is_null($bypass_trash)) { sqgetGlobalVar('bypass_trash', $bypass_trash, SQ_FORM); } sqgetGlobalVar('msg', $msg, SQ_FORM); if (sqgetGlobalVar('account', $iAccount, SQ_FORM) === false) { $iAccount = 0; } $sError = ''; $mailbox = $aMailbox['NAME']; /* retrieve the check boxes */ $aUid = isset($msg) && is_array($msg) ? array_values($msg) : $aUid; if (count($aUid) && $sButton != 'expunge') { // don't do anything to any messages until we have done security check // FIXME: not sure this code really belongs here, but there's nowhere else to put it with this architecture sqgetGlobalVar('smtoken', $submitted_token, SQ_FORM, ''); sm_validate_security_token($submitted_token, -1, TRUE); // make sure message UIDs are sanitized (BIGINT) foreach ($aUid as $i => $uid) { $aUid[$i] = preg_match('/^[0-9]+$/', $uid) ? $uid : '0'; } $aUpdatedMsgs = false; $bExpunge = false; switch ($sButton) { case 'setDeleted': // check if id exists in case we come from read_body if (count($aUid) == 1 && is_array($aMailbox['UIDSET'][$aMailbox['SETINDEX']]) && !in_array($aUid[0], $aMailbox['UIDSET'][$aMailbox['SETINDEX']])) { break; } $aUpdatedMsgs = sqimap_msgs_list_delete($imapConnection, $mailbox, $aUid, $bypass_trash); $bExpunge = true; //} break; case 'unsetDeleted': case 'setSeen': case 'unsetSeen': case 'setFlagged': case 'unsetFlagged': // get flag $sFlag = substr($sButton, 0, 3) == 'set' ? '\\' . substr($sButton, 3) : '\\' . substr($sButton, 5); $bSet = substr($sButton, 0, 3) == 'set' ? true : false; $aUpdatedMsgs = sqimap_toggle_flag($imapConnection, $aUid, $sFlag, $bSet, true); break; case 'move': $aUpdatedMsgs = sqimap_msgs_list_move($imapConnection, $aUid, $targetMailbox, true, $mailbox); sqsession_register($targetMailbox, 'lastTargetMailbox'); $bExpunge = true; break; case 'copy': // sqimap_msgs_list_copy returns true or false. // If error happens - fourth argument handles it inside function. sqimap_msgs_list_copy($imapConnection, $aUid, $targetMailbox, true); sqsession_register($targetMailbox, 'lastTargetMailbox'); break; case 'forward': $aMsgHeaders = array(); foreach ($aUid as $iUid) { $aMsgHeaders[$iUid] = $aMailbox['MSG_HEADERS'][$iUid]; } if (count($aMsgHeaders)) { $composesession = attachSelectedMessages($imapConnection, $aMsgHeaders); // dirty hack, add info to $aMailbox $aMailbox['FORWARD_SESSION']['SESSION_NUMBER'] = $composesession; $aMailbox['FORWARD_SESSION']['UIDS'] = $aUid; } break; default: // Hook for plugin buttons $temp = array(&$sButton, &$aMailbox, $iAccount, $aMailbox['NAME'], &$aUid); do_hook('mailbox_display_button_action', $temp); break; } /** * $aUpdatedMsgs is an array containing the result of the untagged * fetch responses send by the imap server due to a flag change. That * response is parsed in an array with msg arrays by the parseFetch function */ if ($aUpdatedMsgs) { // Update the message headers cache $aDeleted = array(); foreach ($aUpdatedMsgs as $iUid => $aMsg) { if (isset($aMsg['FLAGS'])) { /** * Only update the cached headers if the header is * cached. */ if (isset($aMailbox['MSG_HEADERS'][$iUid])) { $aMailbox['MSG_HEADERS'][$iUid]['FLAGS'] = $aMsg['FLAGS']; } /** * Also update flags in message object */ //FIXME: WHY are we keeping flags in TWO places?!? This is error-prone and some core code uses the is_xxxx message object values while other code uses the flags array above. That's a mess. if (isset($aMailbox['MSG_HEADERS'][$iUid]['MESSAGE_OBJECT'])) { $message = $aMailbox['MSG_HEADERS'][$iUid]['MESSAGE_OBJECT']; $message->is_seen = false; $message->is_answered = false; $message->is_forwarded = false; $message->is_deleted = false; $message->is_flagged = false; $message->is_mdnsent = false; foreach ($aMsg['FLAGS'] as $flag => $value) { if (strtolower($flag) == '\\seen' && $value) { $message->is_seen = true; } else { if (strtolower($flag) == '\\answered' && $value) { $message->is_answered = true; } else { if (strtolower($flag) == '$forwarded' && $value) { $message->is_forwarded = true; } else { if (strtolower($flag) == '\\deleted' && $value) { $message->is_deleted = true; } else { if (strtolower($flag) == '\\flagged' && $value) { $message->is_flagged = true; } else { if (strtolower($flag) == '$mdnsent' && $value) { $message->is_mdnsent = true; } } } } } } } $aMailbox['MSG_HEADERS'][$iUid]['MESSAGE_OBJECT'] = $message; } /** * Count the messages with the \Delete flag set so we can determine * if the number of expunged messages equals the number of flagged * messages for deletion. */ if (isset($aMsg['FLAGS']['\\deleted']) && $aMsg['FLAGS']['\\deleted']) { $aDeleted[] = $iUid; } } } if ($bExpunge && $aMailbox['AUTO_EXPUNGE'] && ($iExpungedMessages = sqimap_mailbox_expunge($imapConnection, $aMailbox['NAME'], true))) { if (count($aDeleted) != $iExpungedMessages) { // there are more messages deleted permanently then we expected // invalidate the cache $aMailbox['UIDSET'][$aMailbox['SETINDEX']] = false; $aMailbox['MSG_HEADERS'] = false; } else { // remove expunged messages from cache $aUidSet = $aMailbox['UIDSET'][$aMailbox['SETINDEX']]; if (is_array($aUidSet)) { // create a UID => array index temp array $aUidSetDummy = array_flip($aUidSet); foreach ($aDeleted as $iUid) { // get the id as well in case of SQM_SORT_NONE if ($aMailbox['SORT'] == SQSORT_NONE) { $aMailbox['ID'] = false; //$iId = $aMailbox['MSG_HEADERS'][$iUid]['ID']; //unset($aMailbox['ID'][$iId]); } // unset the UID and message header unset($aUidSetDummy[$iUid]); unset($aMailbox['MSG_HEADERS'][$iUid]); } $aMailbox['UIDSET'][$aMailbox['SETINDEX']] = array_keys($aUidSetDummy); } } // update EXISTS info if ($iExpungedMessages) { $aMailbox['EXISTS'] -= (int) $iExpungedMessages; $aMailbox['TOTAL'][$aMailbox['SETINDEX']] -= (int) $iExpungedMessages; } if ($aMailbox['PAGEOFFSET'] - 1 >= $aMailbox['EXISTS']) { $aMailbox['PAGEOFFSET'] = $aMailbox['PAGEOFFSET'] > $aMailbox['LIMIT'] ? $aMailbox['PAGEOFFSET'] - $aMailbox['LIMIT'] : 1; $aMailbox['OFFSET'] = $aMailbox['PAGEOFFSET'] - 1; } } } } else { if ($sButton == 'expunge') { /** * on expunge we do not know which messages will be deleted * so it's useless to try to sync the cache * * Close the mailbox so we do not need to parse the untagged expunge * responses which do not contain uid info. * NB: Closing a mailbox is faster then expunge because the imap * server does not need to generate the untagged expunge responses */ sqimap_run_command($imapConnection, 'CLOSE', false, $result, $message); $aMailbox = sqm_api_mailbox_select($imapConnection, $iAccount, $aMailbox['NAME'], array(), array()); } else { // this is the same hook as above, but here it is called in the // context of not having had any messages selected and if any // plugin handles the situation, it should return TRUE so we // know this was not an erroneous user action // global $null; $temp = array(&$sButton, &$aMailbox, $iAccount, $aMailbox['NAME'], $null); if (!boolean_hook_function('mailbox_display_button_action', $temp, 1) && $sButton) { $sError = _("No messages were selected."); } } } return $sError; }