Esempio n. 1
0
 /**
  * Deletes all items with the specified ids for the specified user.
  * The items will only be deleted if all rows in groupware_email_items_flags
  * for the corresponding item have been set to is_deleted=1. Otherwise,
  * only the is_deleted field for the specified user will be set to 1.
  * If that is the case and the item gets entirely deleted, the method will
  * use the accounts-model to check whether there are any accounts flagged
  * as "is_deleted = 1" and also remove this accounts if no more items
  * are exiting in the data storage.
  *
  * @param array $itemIds A numeric array with all id's of the items that are
  * about to be deleted
  * @param integer $userId The id of the user for which the items get deleted.
  *
  * @return integer The number of total rows deleted
  */
 public function deleteItemsForUser(array $itemIds, $userId)
 {
     $userId = (int) $userId;
     if ($userId <= 0) {
         return 0;
     }
     $clearedItemIds = array();
     $cc = 0;
     for ($i = 0, $len = count($itemIds); $i < $len; $i++) {
         $id = (int) $itemIds[$i];
         if ($id > 0) {
             $clearedItemIds[] = $id;
             $cc++;
         }
     }
     if ($cc == 0) {
         return 0;
     }
     $referenceModel = new Conjoon_Modules_Groupware_Email_Item_Model_References();
     // delete all references for the items for the specified user
     $referenceModel->delete('user_id = ' . $userId . ' AND reference_items_id IN (' . implode(',', $clearedItemIds) . ')');
     $flagModel = new Conjoon_Modules_Groupware_Email_Item_Model_Flag();
     $flagModel->flagItemsAsDeleted($clearedItemIds, $userId);
     $deleteValues = $flagModel->areItemsFlaggedAsDeleted($clearedItemIds);
     // if the second argument to array_filter is ommited, array_filter gets
     // all keys which values does not equal to false
     $itemsToDelete = array_filter($deleteValues);
     $idString = implode(',', array_keys($itemsToDelete));
     $deleted = $this->delete('id IN (' . $idString . ')');
     if ($deleted > 0) {
         $referencesModel = new Conjoon_Modules_Groupware_Email_Item_Model_References();
         $inboxModel = new Conjoon_Modules_Groupware_Email_Item_Model_Inbox();
         $outboxModel = new Conjoon_Modules_Groupware_Email_Item_Model_Outbox();
         $attachmentModel = new Conjoon_Modules_Groupware_Email_Attachment_Model_Attachment();
         /**
          * @see Conjoon_Modules_Groupware_Email_Account_Model_Account
          */
         require_once 'Conjoon/Modules/Groupware/Email/Account/Model/Account.php';
         $accountModel = new Conjoon_Modules_Groupware_Email_Account_Model_Account();
         $referencesModel->delete('is_pending=1 AND user_id = ' . $userId . ' AND groupware_email_items_id IN (' . $idString . ')');
         $flagModel->delete('user_id = ' . $userId . ' AND groupware_email_items_id IN (' . $idString . ')');
         $attachmentModel->delete('groupware_email_items_id IN (' . $idString . ')');
         $inboxModel->delete('groupware_email_items_id IN (' . $idString . ')');
         $outboxModel->delete('groupware_email_items_id IN (' . $idString . ')');
         $accountModel->removeAsDeletedFlaggedAccounts($userId);
     }
     return $deleted;
 }
 /**
  * Returns the email items based on the passed POST-parameters to the client.
  * Possible POST parameters are:
  *
  * start - the index in the datastore from where to read the first record
  * limit - the number of records to return
  * dir   - the sort direction, either ASC or DESC
  * sort  - the field to sort. Fields are based upon the properties of the
  *         Conjoon_Modules_Groupware_Email_ItemDto-class and have to be substituted
  *         to their appropriate representatives in the underlying datamodel.
  * groupwareEmailFoldersId - the id of the folder, for which the items should be loaded.
  *                           if this parameter is missing, all emails from all accounts
  *                           will be fetched
  * minDate - this argument is optional - if passed, all emails with a fetched_timestamp
  *           equal to or greater than minDate will be fetched
  *
  *
  * The assigned view variables are:
  *
  * items - an array with objects of Conjoon_Modules_Groupware_Email_ItemDto
  * totalCount - the total count of records available for the requested folder
  *              for this user, or the total count of latest emails for the
  *              user since minDate
  * version - the version property for Ext.ux.grid.BufferedStore
  * pendingItems - if a folder id other than 0 was supplied, the number of
  * pending items will be read out and assigned to this view-variable
  *
  */
 public function getEmailItemsAction()
 {
     require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/Request.php';
     require_once 'Conjoon/Util/Array.php';
     require_once 'Conjoon/Keys.php';
     $auth = Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT);
     $userId = $auth->getIdentity()->getId();
     $CONTEXT_REQUEST_LATEST = Conjoon_Modules_Groupware_Email_Item_Filter_Request::CONTEXT_REQUEST_LATEST;
     $CONTEXT_REQUEST = Conjoon_Modules_Groupware_Email_Item_Filter_Request::CONTEXT_REQUEST;
     if (isset($_POST['minDate']) && !isset($_POST['groupwareEmailFoldersId'])) {
         $context = $CONTEXT_REQUEST_LATEST;
     } else {
         $context = $CONTEXT_REQUEST;
     }
     $itemRequestFilter = new Conjoon_Modules_Groupware_Email_Item_Filter_Request($_POST, $context);
     try {
         $filteredData = $itemRequestFilter->getProcessedData();
     } catch (Zend_Filter_Exception $e) {
         $this->view->success = true;
         $this->view->error = null;
         $this->view->items = array();
         $this->view->version = 1;
         $this->view->totalCount = 0;
         return;
     }
     $sortInfo = array('sort' => $filteredData['sort'], 'dir' => $filteredData['dir'], 'limit' => $filteredData['limit'], 'start' => $filteredData['start']);
     require_once 'Conjoon/BeanContext/Decorator.php';
     require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/ItemResponse.php';
     $itemResponseFilter = new Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse(array(), Conjoon_Filter_Input::CONTEXT_RESPONSE);
     $pendingItems = -1;
     if ($context == $CONTEXT_REQUEST) {
         // check if folder is remote folder
         /**
          * @see Conjoon_Text_Parser_Mail_MailboxFolderPathJsonParser
          */
         require_once 'Conjoon/Text/Parser/Mail/MailboxFolderPathJsonParser.php';
         $parser = new Conjoon_Text_Parser_Mail_MailboxFolderPathJsonParser();
         $pathInfo = $parser->parse($filteredData['path']);
         /**
          * @see Conjoon_Modules_Groupware_Email_Folder_Facade
          */
         require_once 'Conjoon/Modules/Groupware/Email/Folder/Facade.php';
         $facade = Conjoon_Modules_Groupware_Email_Folder_Facade::getInstance();
         if ($facade->isRemoteFolder((int) $pathInfo['rootId'])) {
             /**
              * @see Conjoon_Modules_Groupware_Email_Item_ItemListRequestFacade
              */
             require_once 'Conjoon/Modules/Groupware/Email/Item/ItemListRequestFacade.php';
             $listFacade = Conjoon_Modules_Groupware_Email_Item_ItemListRequestFacade::getInstance();
             $itemData = $listFacade->getEmailItemList($pathInfo, $userId, $sortInfo, true);
             $this->view->success = true;
             $this->view->error = null;
             $this->view->items = $itemData['items'];
             $this->view->version = 1;
             $this->view->totalCount = $itemData['totalCount'];
             $this->view->pendingItems = $itemData['pendingItems'];
             return;
         }
         // get the number of emails currently available for this folder
         // and this user
         require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Item.php';
         require_once 'Conjoon/Modules/Groupware/Email/Folder/Model/Folder.php';
         $folderModel = new Conjoon_Modules_Groupware_Email_Folder_Model_Folder();
         $itemModel = new Conjoon_Modules_Groupware_Email_Item_Model_Item();
         $totalCount = $folderModel->getItemCountForFolderAndUser($filteredData['groupwareEmailFoldersId'], $userId);
         if ($totalCount == 0) {
             $this->view->success = true;
             $this->view->error = null;
             $this->view->items = array();
             $this->view->version = 1;
             $this->view->totalCount = 0;
             $this->view->pendingItems = 0;
             return;
         }
         $decoratedModel = new Conjoon_BeanContext_Decorator($itemModel, $itemResponseFilter);
         $rows = $decoratedModel->getEmailItemsForAsDto($userId, $filteredData['groupwareEmailFoldersId'], $sortInfo);
         $pendingItems = $folderModel->getPendingCountForFolderAndUser($filteredData['groupwareEmailFoldersId'], $userId);
     } else {
         if ($context == $CONTEXT_REQUEST_LATEST) {
             require_once 'Conjoon/BeanContext/Decorator.php';
             require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/ItemResponse.php';
             require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Inbox.php';
             $itemInboxModel = new Conjoon_Modules_Groupware_Email_Item_Model_Inbox();
             $totalCount = $itemInboxModel->getLatestItemCount($userId, $filteredData['minDate']);
             if ($totalCount == 0) {
                 $this->view->success = true;
                 $this->view->error = null;
                 $this->view->items = array();
                 $this->view->version = 1;
                 $this->view->totalCount = 0;
                 return;
             }
             $decoratedModel = new Conjoon_BeanContext_Decorator($itemInboxModel, $itemResponseFilter);
             $rows = $decoratedModel->getLatestEmailItemsForAsDto($userId, $filteredData['minDate'], $sortInfo);
         }
     }
     $this->view->success = true;
     $this->view->error = null;
     $this->view->items = $rows;
     $this->view->pendingItems = $pendingItems;
     $this->view->version = 1;
     $this->view->totalCount = $totalCount;
 }
Esempio n. 3
0
 /**
  * Returns an assoc array with the data of an draft. The returned array
  * has all properties as according to Conjoon_Modules_Groupware_Email_Draft.
  *
  * @param integer $itemId
  * @param integer $userId
  * @param string $context The context used to fetch the draft. Important
  * when dealign with contexts "reply", "reply_all" and "forward".
  * - context "forward": fields "references" and "in_reply_to" will be set
  * to an empty string
  * - context "reply", "reply_all": "in_reply_to" will be set to the message-id
  * of the email, references will be concatenated with the message-id
  *
  * @return array
  */
 public function getDraft($itemId, $userId, $context = '')
 {
     $itemId = (int) $itemId;
     if ($itemId <= 0) {
         return array();
     }
     $itemModel = new Conjoon_Modules_Groupware_Email_Item_Model_Item();
     $row = $itemModel->fetchRow($itemModel->select()->from($itemModel)->where('id = ?', $itemId));
     if (!$row) {
         return array();
     }
     $draft = array('id' => $row->id, 'date' => $row->date, 'subject' => $row->subject, 'from' => $row->from, 'reply_to' => $row->reply_to, 'to' => $row->to, 'cc' => $row->cc, 'bcc' => $row->bcc, 'in_reply_to' => $row->in_reply_to, 'references' => $row->references, 'content_text_plain' => $row->content_text_plain, 'content_text_html' => $row->content_text_html, 'groupware_email_folders_id' => $row->groupware_email_folders_id, 'attachments' => array());
     // clear memory
     unset($row);
     // set in_reply_to, references according to the context
     switch ($context) {
         case Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_REPLY:
         case Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_REPLY_ALL:
             $inboxModel = new Conjoon_Modules_Groupware_Email_Item_Model_Inbox();
             $messageId = $inboxModel->getMessageIdForItem($draft['id']);
             if ($messageId != "") {
                 $draft['in_reply_to'] = $messageId;
                 $draft['references'] = $draft['references'] != '' ? $draft['references'] . ' ' . $messageId : $messageId;
             } else {
                 $draft['in_reply_to'] = '';
                 $draft['references'] = '';
             }
             break;
         case Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_FORWARD:
             $draft['in_reply_to'] = '';
             $draft['references'] = '';
         case '':
         case Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_EDIT:
             /**
              * @see Conjoon_Modules_Groupware_Email_Attachment_Model_Attachment
              */
             require_once 'Conjoon/Modules/Groupware/Email/Attachment/Model/Attachment.php';
             $attachmentModel = new Conjoon_Modules_Groupware_Email_Attachment_Model_Attachment();
             $draft['attachments'] = $attachmentModel->getAttachmentsForItem($draft['id'])->toArray();
             break;
     }
     // check if the item is available in outbox and get the id of it under which it was
     // created. Otherwise, get the standard account out of the accounts-table
     $outboxModel = new Conjoon_Modules_Groupware_Email_Item_Model_Outbox();
     $accIdRow = $outboxModel->fetchRow($outboxModel->select()->from($outboxModel, array('groupware_email_accounts_id'))->where('groupware_email_items_id = ? ', $draft['id']));
     $accountModel = new Conjoon_Modules_Groupware_Email_Account_Model_Account();
     if (!$accIdRow) {
         $accId = $accountModel->getStandardAccountIdForUser($userId);
     } else {
         $accId = $accIdRow->groupware_email_accounts_id;
         // check if the account still exists
         $account = $accountModel->getAccount($accId, $userId);
         if (empty($account)) {
             $accId = $accountModel->getStandardAccountIdForUser($userId);
             if ($accId == 0) {
                 return array();
             }
         }
     }
     $draft['groupware_email_accounts_id'] = $accId;
     return $draft;
 }
Esempio n. 4
0
 /**
  * @param int $userId The id of the user to process the email-accounts for.
  * @param int $accountId The id of the account to fetch the emails for
  *
  * @return Array An associative array with the keys of the fetched and saved
  * emails in the array 'fetched', and error-messages in the key 'errors'.
  */
 private function _fetchEmails($userId, Conjoon_Modules_Groupware_Email_Account $account)
 {
     $fetchedEmailIds = array();
     $fetchedEmailErrors = array();
     $userId = (int) $userId;
     if ($userId <= 0) {
         return $fetchedEmailIds;
     }
     $transports = array(Conjoon_Modules_Groupware_Email_Account::PROTOCOL_POP3 => "Conjoon_Mail_Storage_Pop3", Conjoon_Modules_Groupware_Email_Account::PROTOCOL_IMAP => "Conjoon_Mail_Storage_Imap");
     self::_setIconvEncoding(self::ICONV_UTF_8);
     $accountId = $account->getId();
     $transport = $transports[$account->getProtocol()];
     $isPop3 = $account->getProtocol() == Conjoon_Modules_Groupware_Email_Account::PROTOCOL_POP3;
     $isCopyLeftOnServer = $account->isCopyLeftOnServer();
     $cconf = array('host' => $account->getServerInbox(), 'port' => $account->getPortInbox(), 'user' => $account->getUsernameInbox(), 'password' => $account->getPasswordInbox());
     $ssl = $account->getInboxConnectionType();
     if ($ssl == 'SSL' || $ssl == 'TLS') {
         $cconf['ssl'] = $ssl;
     }
     $mail = new $transport($cconf);
     $hasUniqueId = $mail->hasUniqueId;
     $mailCount = count($mail);
     if ($hasUniqueId) {
         $uidl = $mail->getUniqueId();
         $this->_cacheUidl($uidl, $accountId, $this->_computeChunkSize($mailCount));
         // this is to prevent undefined indexes when the count of uidl
         // differs from the number of emails fetched. This is a very rare error
         // that occures now and then - see http://wiki.conjoon.org/ticket/189
         // it's assumed its related to connection aborts during communication
         // with the mail server
         if (count($uidl) != $mailCount) {
             return array('fetched' => $fetchedEmailIds, 'errors' => array('Could not retrieve messages - number of items in unique id list ' . 'differs from total number of emails on the server: ' . 'Number of unique ids: ' . count($uidl) . '; number of messages: ' . $mailCount . '; ' . 'This is possibly related to a connection abort while attempting to fetch ' . 'messages from a server. Please try again.'));
         }
     }
     $messagesToRemove = array();
     for ($oo = 1; $oo < $mailCount + 1; $oo++) {
         $messageNum = $oo;
         $this->_attachmentCounter = 1;
         $emailItem = array();
         $rawHeader = "";
         $rawBody = "";
         // check if the account supports UIDL, and skip the message
         // if it is already available in the db
         if ($hasUniqueId) {
             if ($this->_isUidPresent($accountId, $uidl[$oo]) === true) {
                 if (!$isCopyLeftOnServer && $isPop3) {
                     $messagesToRemove[] = $messageNum;
                 }
                 continue;
             } else {
                 $emailItem['uid'] = $uidl[$oo];
             }
         }
         // check here if we can process the message, taking memory limit
         // of php ini into account
         if (!$this->_maxMemory) {
             $this->_maxMemory = Conjoon_Util_Format::convertToBytes(ini_get('memory_limit'));
         }
         $s = $mail->getSize($messageNum);
         if ($s == 0) {
             $fetchedEmailErrors[] = 'Could not save message No. ' . $messageNum . ' - message size seems to be 0 bytes';
             continue;
         }
         if ($this->_maxMemory / $s <= 17) {
             $fetchedEmailErrors[] = 'Could not save message No. ' . $messageNum . ' - message could exceed available memory size (' . $this->_maxMemory . ' bytes, message size ' . $s . ').';
             continue;
         }
         self::_splitMessage($mail->getRawMessage($messageNum), $rawHeader, $rawBody);
         $message = new Conjoon_Mail_Message(array('headers' => $rawHeader, 'noToplines' => true, 'content' => $rawBody));
         $messageId = "";
         try {
             $messageId = $message->messageId;
         } catch (Zend_Mail_Exception $e) {
             // ignore
         }
         $emailItem['messageId'] = $messageId;
         $mail->noop();
         // check here if we can remove the mail from the server
         // check first if UIDL is supported. if not, look up the
         // message
         if (!$hasUniqueId) {
             $id = $this->_isMessageIdPresent($messageId, $accountId, $rawHeader, $rawBody);
             $mail->noop();
             if ($id === true) {
                 if (!$isCopyLeftOnServer && $isPop3) {
                     $messagesToRemove[] = $messageNum;
                 }
                 continue;
             }
         } else {
             if (!$isCopyLeftOnServer && $isPop3) {
                 $messagesToRemove[] = $messageNum;
             }
         }
         $mail->noop();
         $emailItem['attachments'] = array();
         $emailItem['userId'] = $userId;
         try {
             $emailItem['from'] = $message->from;
         } catch (Zend_Mail_Exception $e) {
             // may be changed to localized header values by anti vir programs
             try {
                 $emailItem['from'] = $message->von;
             } catch (Zend_Mail_Exception $e) {
                 $emailItem['from'] = "-";
             }
         }
         if (!isset($emailItem['from'])) {
             throw new Zend_Mail_Exception("No header with the name \"from\" found. Please check if you have an anti virus program runnning in the background. Some are known to change the header values to localized derivates.");
         }
         $emailItem['subject'] = "";
         // very few emails will come in without a subject.
         try {
             $emailItem['subject'] = $message->subject;
         } catch (Zend_Mail_Exception $e) {
             try {
                 // may be changed to localized header values by anti vir programs
                 $emailItem['subject'] = $message->betreff;
             } catch (Zend_Mail_exception $e) {
                 // ignore
             }
         } catch (Zend_Mail_exception $e) {
             // ignore
         }
         $emailItem['date'] = "";
         // date field will be given presedence
         try {
             $emailItem['date'] = $message->date;
         } catch (Zend_Mail_Exception $e) {
             // ignore
         }
         // if date not found, look up deliveryDate
         if (!$emailItem['date']) {
             try {
                 $emailItem['date'] = $message->deliveryDate;
             } catch (Zend_Mail_Exception $e) {
                 // ignore
             }
             if (!$emailItem['date']) {
                 try {
                     // may be changed to localized header values by anti vir programs
                     $emailItem['date'] = $message->datum;
                 } catch (Zend_Mail_Exception $e) {
                     // ignore
                 }
                 // and one further down to fall back to actual
                 // date if none was found
                 if (!$emailItem['date']) {
                     /**
                      * @see Zend_Date
                      */
                     require_once 'Zend/Date.php';
                     $zd = new Zend_Date();
                     $emailItem['date'] = $zd->get(Zend_Date::RFC_2822);
                 }
             }
         }
         try {
             $emailItem['to'] = $message->to;
         } catch (Zend_Mail_Exception $e) {
             // "to" might not be used, instead "cc" will be probably available
             // then
             $emailItem['to'] = "";
         }
         if (!$emailItem['to']) {
             try {
                 // may be changed to localized header values by anti vir programs
                 $emailItem['to'] = $message->an;
             } catch (Zend_Mail_Exception $e) {
                 // ignore
             }
         }
         try {
             $emailItem['cc'] = $message->cc;
         } catch (Zend_Mail_Exception $e) {
             $emailItem['cc'] = '';
         }
         try {
             $emailItem['references'] = $message->references;
         } catch (Zend_Mail_Exception $e) {
             $emailItem['references'] = '';
         }
         try {
             $emailItem['replyTo'] = $message->replyTo;
         } catch (Zend_Mail_Exception $e) {
             $emailItem['replyTo'] = '';
         }
         try {
             $emailItem['inReplyTo'] = $message->inReplyTo;
         } catch (Zend_Mail_Exception $e) {
             $emailItem['inReplyTo'] = '';
         }
         $encodingInformation = $this->_getEncodingInformation($message);
         $contentType = $encodingInformation['contentType'];
         $mail->noop();
         try {
             switch ($contentType) {
                 case 'text/plain':
                     $emailItem['contentTextPlain'] = $this->_decode($message->getContent(), $encodingInformation);
                     break;
                 case 'text/html':
                     $emailItem['contentTextHtml'] = $this->_decode($message->getContent(), $encodingInformation);
                     break;
                 case 'multipart/mixed':
                     $this->_parseMultipartMixed($message, $emailItem);
                     break;
                 case 'multipart/alternative':
                     $this->_parseMultipartAlternative($message, $emailItem);
                     break;
                 case 'multipart/related':
                     $this->_parseMultipartRelated($message, $emailItem);
                     break;
                 case 'multipart/signed':
                     $this->_parseMultipartSigned($message, $emailItem);
                     break;
                 case 'multipart/report':
                     $this->_parseMultipartReport($message, $emailItem);
                     break;
                 default:
                     $emailItem['contentTextPlain'] = $this->_decode($message->getContent(), $encodingInformation);
                     break;
             }
         } catch (Exception $e) {
             $fetchedEmailErrors[] = "Could not save message No. " . $messageNum . " with the subject \"" . $emailItem['subject'] . "\". " . "An unexpected error occurred: \"" . $e->getMessage() . "\"";
             $mail->noop();
             continue;
         }
         $mail->noop();
         if (!isset($emailItem['contentTextPlain'])) {
             $emailItem['contentTextPlain'] = '';
         }
         if (!isset($emailItem['contentTextHtml'])) {
             $emailItem['contentTextHtml'] = '';
         }
         $this->_assignJunkStatus($userId, $emailItem);
         $this->_assignFolderId($userId, $accountId, $emailItem);
         $emailItem['rawHeader'] =& $rawHeader;
         $emailItem['rawBody'] =& $rawBody;
         $mail->noop();
         if (!$emailItem['messageId']) {
             $emailItem['hash'] = Conjoon_Modules_Groupware_Email_Item_Model_Inbox::computeMessageHash($rawHeader, $rawBody);
         }
         $mail->noop();
         $saved = $this->_saveEmail($emailItem, $userId);
         $mail->noop();
         if (is_int($saved) > 0) {
             $fetchedEmailIds[] = $saved;
         } else {
             $fetchedEmailErrors[] = "Could not save Email Message with the " . " subject \"" . $emailItem['subject'] . "\"" . ", date \"" . $emailItem['date'] . "\"" . ": " . $saved;
             continue;
         }
         $mail->noop();
         if (!$isCopyLeftOnServer && $isPop3) {
             $messagesToRemove[] = $messageNum;
         }
     }
     $messagesToRemove = array_unique($messagesToRemove);
     foreach ($messagesToRemove as $id) {
         $mail->removeMessage($id);
     }
     self::_setIconvEncoding(self::ICONV_OLD);
     return array('fetched' => $fetchedEmailIds, 'errors' => $fetchedEmailErrors);
 }