/**
  * the singleton pattern
  *
  * @return Expressomail_Controller_Message_Flags
  */
 public static function getInstance()
 {
     if (self::$_instance === NULL) {
         self::$_instance = new Expressomail_Controller_Message_Flags();
     }
     return self::$_instance;
 }
 /**
  * Send the reading confirmation in a message who has the correct header and is not seen yet
  *
  * @return void
  */
 public function sendReadingConfirmation()
 {
     if (!is_array($this->headers)) {
         $this->headers = Expressomail_Controller_Message::getInstance()->getMessageHeaders($this->getId(), NULL, TRUE);
     }
     if (array_key_exists('disposition-notification-to', $this->headers) && $this->headers['disposition-notification-to'] && !$this->hasSeenFlag() && !$this->hasReadFlag() && !$this->hasDraftFlag()) {
         $translate = Tinebase_Translation::getTranslation($this->_application);
         $from = Expressomail_Controller_Account::getInstance()->get($this->account_id);
         $arrRet = array();
         preg_match(Tinebase_Mail::EMAIL_ADDRESS_REGEXP, $this->headers['disposition-notification-to'], $arrRet);
         $to = $arrRet[0];
         if ($from->email === $to) {
             return;
         }
         // calculate timezone in "GMT-HH:MM" format
         $dtz = new DateTimeZone(Tinebase_Core::get(Tinebase_Core::USERTIMEZONE));
         $time = new DateTime('now', $dtz);
         $offset = $dtz->getOffset($time);
         $sign = $offset < 0 ? "-" : "+";
         $offset = abs($offset);
         $hours = floor($offset / 3600);
         $hours = $hours < 10 ? '0' . $hours : $hours;
         $minutes = offset % 60;
         $minutes = $minutes < 10 ? '0' . $minutes : $minutes;
         $gmt = '(GMT' . $sign . $hours . ":" . $minutes . ')';
         $subject = $translate->_('Reading Confirmation:') . ' ' . $this->subject;
         $readTime = date('Y-m-d H:i:s');
         $tzReadTime = Tinebase_Translation::dateToStringInTzAndLocaleFormat(Expressomail_Message::convertDate($readTime));
         $tzReceived = Tinebase_Translation::dateToStringInTzAndLocaleFormat(Expressomail_Message::convertDate($this->received));
         $messageBody = $translate->_('Your message:') . ' ' . $this->subject . "\n" . $translate->_('Received on') . ' ' . $tzReceived . ' ' . $gmt . "\n" . $translate->_('Was read by:') . ' ' . $from->from . ' <' . $from->email . '> ' . $translate->_('on') . ' ' . $tzReadTime . ' ' . $gmt;
         //$messageBody         = Expressomail_Message::convertFromTextToHTML($messageBody);
         $readconf = array('to' => $to, 'subject' => $this->subject, 'received' => $this->received, 'from_name' => $from->from, 'from_email' => $from->email, 'read_time' => $readTime);
         $mailPart = new Zend_Mime_Part(serialize($readconf));
         $mailPart->charset = 'UTF-8';
         $mailPart->type = 'text/readconf;';
         $mailPart->encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE;
         $contact = new Addressbook_Model_Contact(array('email' => $to, 'n_fn' => $from->from), true);
         $result = Tinebase_Notification::getInstance()->send(Tinebase_Core::getUser(), array($contact), $subject, $messageBody, $mailPart, NULL);
         Expressomail_Controller_Message_Flags::getInstance()->addFlags($this->getId(), (array) 'Read');
     }
 }
 /**
  * get complete message by id
  *
  * @param string|Expressomail_Model_Message  $_id
  * @param string                            $_partId
  * @param boolean                          $_setSeen
  * @return Expressomail_Model_Message
  */
 public function getCompleteMessage($_id, $_partId = NULL, $_setSeen = FALSE)
 {
     if ($_id instanceof Expressomail_Model_Message) {
         $message = $_id;
     } else {
         $message = $this->get($_id);
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Getting message content ' . $message->messageuid);
     }
     $folder = Expressomail_Controller_Folder::getInstance()->get($message->folder_id);
     $account = Expressomail_Controller_Account::getInstance()->get($folder->account_id);
     $this->_checkMessageAccount($message, $account);
     $message = $this->_getCompleteMessageContent($message, $account, $_partId);
     if ($_setSeen) {
         Expressomail_Controller_Message_Flags::getInstance()->setSeenFlag($message);
     }
     $this->prepareAndProcessParts($message);
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($message->toArray(), true));
     }
     return $message;
 }
 /**
  * test delete in different accounts
  */
 public function testDeleteMessagesInDifferentAccounts()
 {
     $clonedAccount = $this->_cloneAccount();
     $trashFolderMainAccount = $this->getFolder('Trash');
     $trashFolderClonedAccount = $this->getFolder('Trash', $clonedAccount);
     // empty trash
     Expressomail_Controller_Folder::getInstance()->emptyFolder($trashFolderMainAccount);
     $cachedMessage1 = $this->messageTestHelper('multipart_mixed.eml', 'multipart/mixed', $trashFolderMainAccount);
     $cachedMessage2 = $this->messageTestHelper('complete.eml', 'text/service', $trashFolderClonedAccount);
     Expressomail_Controller_Message_Flags::getInstance()->addFlags(array($cachedMessage1->getId(), $cachedMessage2->getId()), array(Zend_Mail_Storage::FLAG_DELETED));
     $result1 = $this->_searchOnImap('multipart/mixed', $trashFolderMainAccount);
     $this->assertEquals(0, count($result1), $trashFolderMainAccount->globalname . ' still contains multipart/mixed messages:' . print_r($result1, TRUE));
     $result2 = $this->_searchOnImap('text/service', $trashFolderClonedAccount);
     $this->assertEquals(0, count($result2), $trashFolderClonedAccount->globalname . ' still contains text/service messages:' . print_r($result2, TRUE));
 }
 /**
  * send mail via transport (smtp)
  *
  * @param Zend_Mail $_mail
  * @param Expressomail_Model_Account $_account
  * @param boolean $_saveInSent
  * @param Expressomail_Model_Message $_message
  */
 protected function _sendMailViaTransport(Zend_Mail $_mail, Expressomail_Model_Account $_account, Expressomail_Model_Message $_message = NULL, $_saveInSent = false)
 {
     $smtpConfig = $_account->getSmtpConfig();
     if (!empty($smtpConfig) && array_key_exists('hostname', $smtpConfig)) {
         $transport = new Expressomail_Transport($smtpConfig['hostname'], $smtpConfig);
         // send message via smtp
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' About to send message via SMTP ...');
         }
         Tinebase_Smtp::getInstance()->sendMessage($_mail, $transport);
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' successful.');
         }
         // append mail to sent folder
         if ($_saveInSent) {
             $this->_selectSentFolder($_message, $_account);
             $this->_saveInSent($transport, $_account, $this->_getAdditionalHeaders($_message));
         }
         if ($_message !== NULL) {
             // add reply/forward flags if set
             if (!empty($_message->flags) && ($_message->flags == Zend_Mail_Storage::FLAG_ANSWERED || $_message->flags == Zend_Mail_Storage::FLAG_PASSED) && $_message->original_id instanceof Expressomail_Model_Message) {
                 Expressomail_Controller_Message_Flags::getInstance()->addFlags($_message->original_id, array($_message->flags));
             }
         }
     } else {
         Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not send message, no smtp config found.');
     }
 }
 /**
  * (non-PHPdoc)
  * @see ActiveSync_Frontend_Abstract::updateEntry()
  */
 public function updateEntry($folderId, $serverId, Syncroton_Model_IEntry $entry)
 {
     $folderBackend = Syncroton_Registry::get(Syncroton_Registry::FOLDERBACKEND);
     $folder = $folderBackend->getFolder($this->_device, $folderId);
     $bigContentId = $this->getBigContentId($folder->id, $serverId);
     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " CollectionId: {$folderId} Id: {$serverId}");
     }
     try {
         $message = $this->_contentController->get($bigContentId);
     } catch (Tinebase_Exception_NotFound $tenf) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $tenf);
         }
         throw new Syncroton_Exception_NotFound($tenf->getMessage());
     }
     if (isset($entry->read)) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " CollectionId: {$folderId} Id: {$bigContentId} set read flag: {$entry->read}");
         }
         if ($entry->read == 1) {
             Expressomail_Controller_Message_Flags::getInstance()->addFlags($bigContentId, Zend_Mail_Storage::FLAG_SEEN);
         } else {
             Expressomail_Controller_Message_Flags::getInstance()->clearFlags($bigContentId, Zend_Mail_Storage::FLAG_SEEN);
         }
     }
     if (isset($entry->flag)) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " CollectionId: {$folderId} Id: {$bigContentId} set flagged flag: {$entry->flag->status}");
         }
         if ($entry->flag->status == Syncroton_Model_EmailFlag::STATUS_ACTIVE) {
             Expressomail_Controller_Message_Flags::getInstance()->addFlags($bigContentId, Zend_Mail_Storage::FLAG_FLAGGED);
         } else {
             Expressomail_Controller_Message_Flags::getInstance()->clearFlags($bigContentId, Zend_Mail_Storage::FLAG_FLAGGED);
         }
     }
     $message->timestamp = $this->_syncTimeStamp;
     $this->_contentController->update($message);
     return;
 }
 /**
  * test flag update
  */
 public function testUpdateFlags()
 {
     $message = $this->_emailTestClass->messageTestHelper('multipart_mixed.eml', 'multipart/mixed');
     // appended messages already have the SEEN flag
     $this->assertTrue(in_array(Zend_Mail_Storage::FLAG_SEEN, $message->flags), 'SEEN flag not found: ' . print_r($message->flags, TRUE));
     // add another flag
     Expressomail_Controller_Message_Flags::getInstance()->addFlags($message, Zend_Mail_Storage::FLAG_ANSWERED);
     while (!isset($updatedFolder) || $updatedFolder->cache_status === Expressomail_Model_Folder::CACHE_STATUS_INCOMPLETE) {
         $updatedFolder = $this->_controller->updateCache($this->_folder, 30, 1);
     }
     // clear/add flag on imap
     $this->_imap->clearFlags($message->messageuid, array(Zend_Mail_Storage::FLAG_SEEN));
     $flagsToAdd = array(Zend_Mail_Storage::FLAG_FLAGGED, Zend_Mail_Storage::FLAG_DRAFT, Zend_Mail_Storage::FLAG_PASSED);
     try {
         $this->_imap->addFlags($message->messageuid, $flagsToAdd);
     } catch (Zend_Mail_Storage_Exception $zmse) {
         // some imap servers (dbmail, ...) do not support PASSED flag
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $zmse->getMessage());
         }
         $this->_imap->addFlags($message->messageuid, array(Zend_Mail_Storage::FLAG_FLAGGED, Zend_Mail_Storage::FLAG_DRAFT));
     }
     $this->_controller->updateFlags($updatedFolder);
     $cachedMessage = Expressomail_Controller_Message::getInstance()->get($message->getId());
     $this->assertTrue(!in_array(Zend_Mail_Storage::FLAG_SEEN, $cachedMessage->flags), 'SEEN flag found: ' . print_r($cachedMessage->flags, TRUE));
     $expectedFlags = array(Zend_Mail_Storage::FLAG_FLAGGED, Zend_Mail_Storage::FLAG_DRAFT, Zend_Mail_Storage::FLAG_ANSWERED);
     $this->assertEquals(3, count($cachedMessage->flags), 'found too many flags: ' . print_r($cachedMessage->flags, TRUE));
     foreach ($expectedFlags as $expectedFlag) {
         $this->assertTrue(in_array($expectedFlag, $cachedMessage->flags), $expectedFlag . ' flag not found: ' . print_r($cachedMessage->flags, TRUE));
     }
     $this->_controller->updateFlags($updatedFolder);
     $cachedMessageAgain = Expressomail_Controller_Message::getInstance()->get($message->getId());
     // cached message should not have been updated again
     $this->assertEquals($cachedMessage->timestamp->__toString(), $cachedMessageAgain->timestamp->__toString());
 }
 /**
  * Returns registry data of expressomail.
  * 
  * @see Tinebase_Application_Json_Abstract
  *
  * @return mixed array 'variable name' => 'data'
  *        
  * @todo get default account data (host, port, ...) from preferences?
  */
 public function getRegistryData()
 {
     try {
         $accounts = $this->searchAccounts('');
     } catch (Exception $e) {
         Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not get accounts: ' . $e->getMessage());
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $e->getTraceAsString());
         }
         $accounts = array('results' => array(), 'totalcount' => 0);
     }
     $supportedFlags = Expressomail_Controller_Message_Flags::getInstance()->getSupportedFlags();
     $extraSenderAccounts = array();
     foreach ($accounts['results'] as $key => $account) {
         try {
             // build a imap backend so the system folder can be created if necessary
             $accountModel = Expressomail_Controller_Account::getInstance()->get($account['id']);
             $accountModel->resolveCredentials(FALSE);
             // force update the user credentials
             $imapConfig = $imapConfig = Tinebase_Config::getInstance()->get(Tinebase_Config::IMAP, new Tinebase_Config_Struct());
             $config = new stdClass();
             $config->{'host'} = $imapConfig->{'host'};
             $config->{'port'} = $imapConfig->{'port'};
             $config->{'ssl'} = $imapConfig->{'ssl'};
             $config->{'user'} = $accountModel->getUsername();
             $config->{'password'} = $accountModel->{'password'};
             $imap = Expressomail_Backend_ImapFactory::factory($account['id']);
             if ($imap->createDefaultImapSystemFoldersIfNecessary($config)) {
                 try {
                     // add the namespace 'INBOX/' to the new folders
                     $capabilities = $imap->getCapabilityAndNamespace();
                     Expressomail_Controller_Account::getInstance()->updateNamespacesAndDelimiter($accountModel, $capabilities);
                     // update account info in backend and session
                     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                         Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Updating capabilities for account: ' . $accountModel->name);
                     }
                     Expressomail_Controller_Account::getInstance()->getBackend()->update($accountModel);
                     // save capabilities in SESSION
                     Expressomail_Session::getSessionNamespace()->account[$accountModel->getId()] = $capabilities;
                 } catch (Exception $zdse) {
                     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $zdse->getTraceAsString());
                     }
                 }
             }
         } catch (Exception $e) {
             if (Tinebase_Core::isLogLevel(Zend_Log::ERR)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Exception: ' . $e->getMessage());
             }
         }
         try {
             $extraSenderAccounts = Expressomail_Controller_Folder::getInstance()->getUsersWithSendAsAcl($account['id']);
         } catch (Expressomail_Exception_IMAPFolderNotFound $ex) {
             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . $ex->getMessage());
             }
             // Ignore this exception here, it happens when INBOX folder is unaccessible.
         } catch (Expressomail_Exception_IMAPServiceUnavailable $ex) {
             // Ignoring this Exception here.
         }
         unset($account['host']);
         unset($account['port']);
         unset($account['ssl']);
         unset($account['smtp_hostname']);
         unset($account['smtp_port']);
         unset($account['smtp_ssl']);
         unset($account['smtp_auth']);
         $accounts['results'][$key] = $account;
     }
     $result = array('extraSenderAccounts' => $extraSenderAccounts, 'accounts' => $accounts, 'supportedFlags' => array('results' => $supportedFlags, 'totalcount' => count($supportedFlags)), 'aspellDicts' => Tinebase_Core::getConfig()->aspellDicts);
     // TODO: get balanceid cookie name from config
     $balanceIdCookieName = 'BALANCEID';
     if (isset($_COOKIE[$balanceIdCookieName])) {
         $result['balanceId'] = array('cookieName' => $balanceIdCookieName, 'cookieValue' => $_COOKIE[$balanceIdCookieName]);
     }
     $result['vacationTemplates'] = $this->getVacationMessageTemplates();
     $config = Tinebase_Core::getConfig();
     $result['useKeyEscrow'] = $config->certificate->active && $config->certificate->useKeyEscrow;
     $config = Expressomail_Controller::getInstance()->getConfigSettings(false);
     // add autoSaveDraftsInterval to client registry
     $result['autoSaveDraftsInterval'] = $config->autoSaveDraftsInterval;
     // add reportPhishingEmail to client registry
     $result['reportPhishingEmail'] = $config->reportPhishingEmail;
     return $result;
 }