/** * Deletes a folder and all related data permanently from the datastore. * * @todo The method will first try to delete the folder related data primary, * and signal a successfull operation even if other contextual data (such as * email items stored in this folder) could not be deleted. In this case, * a script should from time to time determine which email items etc. are * not related to a folder anymore. * * @param integer $id The id of the folder to delete * @param integer $userId The id of the user to delete the data for * @param boolean $checkForDeletable Check whether the folder may get deleted * * @return integer 0 if the folder was not deleted, otherwise 1 (equals to * the number of deleted folders) */ public function deleteFolder($id, $userId, $checkForDeletable = true) { $id = (int) $id; $userId = (int) $userId; if ($id <= 0 || $userId <= 0) { return 0; } // check first if the folder may get deleted if ($checkForDeletable && !$this->isFolderDeletable($id, $userId)) { return 0; } $where = $this->getAdapter()->quoteInto('id = ?', $id, 'INTEGER'); $affected = $this->delete($where); /** * @see Conjoon_Modules_Groupware_Email_Folder_Model_FoldersUsers */ require_once 'Conjoon/Modules/Groupware/Email/Folder/Model/FoldersUsers.php'; $faModel = new Conjoon_Modules_Groupware_Email_Folder_Model_FoldersUsers(); $faModel->deleteForFolder($id); /** * @see Conjoon_Modules_Groupware_Email_Folder_Model_FoldersAccounts */ require_once 'Conjoon/Modules/Groupware/Email/Folder/Model/FoldersAccounts.php'; $faModel = new Conjoon_Modules_Groupware_Email_Folder_Model_FoldersAccounts(); $faModel->deleteForFolder($id); /** * @see Conjoon_Modules_Groupware_Email_Item_Model_Item */ require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Item.php'; $itemModel = new Conjoon_Modules_Groupware_Email_Item_Model_Item(); $itemModel->deleteItemsForFolder($id, $userId); return $affected; }
private function _removeInformationForAccountIf($accountId, $userId) { /** * @see Conjoon_Modules_Groupware_Email_Folder_Model_FoldersAccounts */ require_once 'Conjoon/Modules/Groupware/Email/Folder/Model/FoldersAccounts.php'; $foldersAccounts = new Conjoon_Modules_Groupware_Email_Folder_Model_FoldersAccounts(); /** * @see Conjoon_Modules_Groupware_Email_Item_Model_Item */ require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Item.php'; $itemModel = new Conjoon_Modules_Groupware_Email_Item_Model_Item(); $folders = $foldersAccounts->getFolderIdsForAccountId($accountId); $del = true; for ($i = 0, $len = count($folders); $i < $len; $i++) { $count = $itemModel->getEmailItemCountForFolder($folders[$i]); if ($count > 0) { $del = false; break; } } if ($del) { // remove account-data entirely - as for accounts_root data specified $where = $this->getAdapter()->quoteInto('id = ?', $accountId, 'INTEGER'); $deleted = $this->delete($where); if ($deleted) { // delete account-mappings $foldersAccounts->deleteForAccountId($accountId); return $accountId; } } return 0; }
/** * Fetches all email items for the specified user where fetched_timestamp * is greater than or equal to $minDate. This query will respect * all accounts of the user and all folders that are of the meta-type * 'inbox'. * * * @param integer $userId The id of the user * @param integer $minDate A timestamp * @param array $sortInfo An array with sortInfo. * * @return array */ public function getLatestEmailItemsFor($userId, $minDate, array $sortInfo) { if ((int) $userId <= 0 || (int) $minDate < 0) { return array(); } // fetch the requested range of email items $adapter = self::getDefaultAdapter(); require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Item.php'; $itemModel = new Conjoon_Modules_Groupware_Email_Item_Model_Item(); $select = Conjoon_Modules_Groupware_Email_Item_Model_Item::getItemBaseQuery($userId, $sortInfo, array('name' => array('inbox' => self::getTablePrefix() . 'groupware_email_items_inbox'), 'cols' => array())); $select = $select->join(array('accounts' => self::getTablePrefix() . 'groupware_email_accounts'), $adapter->quoteInto('`accounts`.`user_id` = ?', $userId, 'INTEGER') . ' AND ' . '`accounts`.`is_deleted` = 0', array())->join(array('foldersaccounts' => self::getTablePrefix() . 'groupware_email_folders_accounts'), 'foldersaccounts.groupware_email_accounts_id=accounts.id', array())->where('items.groupware_email_folders_id=foldersaccounts.groupware_email_folders_id' . ' AND ' . '`inbox`.`groupware_email_items_id`=`items`.`id`' . ' AND ' . $adapter->quoteInto('`inbox`.`fetched_timestamp` >= ?', $minDate, 'INTEGER')); $rows = $adapter->fetchAll($select); if ($rows != false) { return $itemModel->applyPathToEmailItems($rows); } return array(); }
/** * Saves a draft into the database for later editing /sending. * * Incoming data will be filtered and then saved into the database. * * * */ public function saveDraftAction() { /** * @see Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput */ require_once 'Conjoon/Modules/Groupware/Email/Draft/Filter/DraftInput.php'; try { // the filter will transform the "message" into bodyHtml and bodyText, depending // on the passed format. both will only be filled if format equals to "multipart" $filter = new Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput($_POST, Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput::CONTEXT_DRAFT); $data = $filter->getProcessedData(); } catch (Exception $e) { require_once 'Conjoon/Error.php'; $error = Conjoon_Error::fromFilter($filter, $e); $this->view->success = false; $this->view->error = $error->getDto(); $this->view->item = null; return; } /** * @see Conjoon_Modules_Groupware_Email_Address */ require_once 'Conjoon/Modules/Groupware/Email/Address.php'; /** * @see Conjoon_Modules_Groupware_Email_Draft */ require_once 'Conjoon/Modules/Groupware/Email/Draft.php'; /** * @see Conjoon_BeanContext_Inspector */ require_once 'Conjoon/BeanContext/Inspector.php'; // create the message object here $to = array(); $cc = array(); $bcc = array(); $postedAttachments = $data['attachments']; $data['attachments'] = array(); $removeAttachmentIds = $data['removedAttachments']; unset($data['removedAttachments']); foreach ($data['cc'] as $dcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dcc); $cc[] = $add; } foreach ($data['bcc'] as $dbcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dbcc); $bcc[] = $add; } foreach ($data['to'] as $dto) { $add = new Conjoon_Modules_Groupware_Email_Address($dto); $to[] = $add; } $data['cc'] = $cc; $data['to'] = $to; $data['bcc'] = $bcc; // get the specified account for the user require_once 'Conjoon/BeanContext/Decorator.php'; require_once 'Conjoon/Keys.php'; $accountDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Account_Model_Account'); $auth = Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT); $userId = $auth->getIdentity()->getId(); $account = $accountDecorator->getAccountAsEntity($data['groupwareEmailAccountsId'], $userId); // no account found? if (!$account) { $this->view->error = $this->getErrorDto('Error while saving email', 'Could not find specified account.', Conjoon_Error::LEVEL_ERROR); $this->view->success = false; $this->view->item = null; return; } $draft = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Draft', $data, true); // check whether we need to apply attachments for a previously saved // draft if ($draft->getId() > 0 && $account->getProtocol() != 'IMAP') { /** * @see Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse */ require_once 'Conjoon/Modules/Groupware/Email/Attachment/Filter/AttachmentResponse.php'; $attDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Attachment_Model_Attachment', new Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse(array(), Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse::CONTEXT_RESPONSE)); $atts = $attDecorator->getAttachmentsForItemAsEntity($draft->getId()); $draft->setAttachments($atts); } /** * @see Conjoon_BeanContext_Decorator */ require_once 'Conjoon/BeanContext/Decorator.php'; /** * @see Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse */ require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/ItemResponse.php'; /** * @see Conjoon_Modules_Groupware_Email_Item_Model_Item */ require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Item.php'; $itemModel = new Conjoon_Modules_Groupware_Email_Item_Model_Item(); $attachmentMap = array(); if ($account->getProtocol() == 'IMAP') { $this->saveDraftForImap($draft, $account, $userId, $data['type'], $data['referencedData'], $postedAttachments, $removeAttachmentIds, $attachmentMap, $userId); return; } $item = $itemModel->saveDraft($draft, $account, $userId, $data['type'], $data['referencesId'], $postedAttachments, $removeAttachmentIds, $attachmentMap); if (!$item || empty($item)) { $this->view->error = $this->getErrorDto('Error while saving email', 'The email could not be stored into the database.', Conjoon_Error::LEVEL_ERROR); $this->view->success = false; $this->view->item = null; return; } /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; Conjoon_Util_Array::camelizeKeys($item); $irFilter = new Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse($item, Conjoon_Filter_Input::CONTEXT_RESPONSE); $item = $irFilter->getProcessedData(); $item = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Item', $item)->getDto(); /** * @see Conjoon_Modules_Groupware_Email_Message_Facade */ require_once 'Conjoon/Modules/Groupware/Email/Message/Facade.php'; $emailRecord = Conjoon_Modules_Groupware_Email_Message_Facade::getInstance()->getMessage($item->id, $this->_helper->registryAccess()->getUserId(), true, $data['path']); // silently add old ids to new ids from attachmentMap $attachments =& $emailRecord->attachments; foreach ($attachmentMap as $orgId => $newId) { for ($i = 0, $len = count($attachments); $i < $len; $i++) { if ($attachments[$i]->id == $newId) { $attachments[$i]->oldId = $orgId; } } } $this->view->error = null; $this->view->success = true; $this->view->item = $item; $this->view->emailRecord = $emailRecord; }
/** * 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; }
/** * Moves all items to the folder with the specified id. * * Based on the given context, Post data will be in different format. * In Json context, there will be a post value named "json", holding the * item's id with their target folder as an associative array: * {id : integer, groupwareEmailFoldersId : integer } * * * */ public function moveItemsAction() { if ($this->_helper->conjoonContext()->getCurrentContext() == self::CONTEXT_JSON) { require_once 'Zend/Json.php'; $toMove = Zend_Json::decode($_POST['itemsToMove'], Zend_Json::TYPE_ARRAY); $fromPath = $_POST['fromPath']; $toPath = $_POST['toPath']; } if ($this->imapItemsMoved($toMove, $fromPath, $toPath)) { $this->view->success = true; $this->view->error = null; return; } require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/Item.php'; $filter = new Conjoon_Modules_Groupware_Email_Item_Filter_Item(array(), Conjoon_Modules_Groupware_Email_Item_Filter_Item::CONTEXT_MOVE); $moveData = array(); for ($i = 0, $len = count($toMove); $i < $len; $i++) { $filteredData = $filter->setData($toMove[$i])->getProcessedData(); if (!isset($moveData[$filteredData['groupwareEmailFoldersId']])) { $moveData[$filteredData['groupwareEmailFoldersId']] = array(); } $moveData[$filteredData['groupwareEmailFoldersId']][] = $filteredData['id']; } require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Item.php'; $model = new Conjoon_Modules_Groupware_Email_Item_Model_Item(); foreach ($moveData as $folderId => $itemIds) { $model->moveItemsToFolder($itemIds, $folderId); } $this->view->success = true; $this->view->error = null; }
/** * Sends an email to the specified recipients. * The action expects the following arguments to be passed: * * - format: The format the email should be send. Can default to * "text/plain", "text/html" - or "multipart" if the email should * be send both as html and plain-text. * - id: The id of the messge if this was loaded from an already existing * draft (i.e. a draft, an email that is being replied to which is being forwarded). * -type: The type of teh action: if this equals to "reply", "reply_all" or "forward", * this message references an existing one * Can default to 0 or -1 if the emil was created from the scratch * - groupwareEmailAccountsId: An integer specifying the id of the email account of the * user which will be used to send the message * - groupwareEmailFoldersId: The id of the folder from which this email was opened. Equals * to -1 or 0 if the messge was created from scratch * - subject: The subject of the message * - message: The message as edited in the browser. Will most likely have * HTML tags in it depending on the editor used * - to: An json encoded array with all addresses being specified in the "to" * field. Addresses may be separated by a comma "," or a semicolon ";" * - cc: An json encoded array with all addresses being specified in the "cc" * field. Addresses may be separated by a comma "," or a semicolon ";" * - bcc: An json encoded array with all addresses being specified in the "bcc" * field. Addresses may be separated by a comma "," or a semicolon ";" * - attachments: An array with attachments, structure according to * com.conjoon.cudgets.data.FileRecord. ids for files will be stored in * the orgId property * The view awaits a fully configured email item as the response. */ public function sendAction() { require_once 'Conjoon/Modules/Groupware/Email/Draft/Filter/DraftInput.php'; $data = array(); try { // the filter will transform the "message" into bodyHtml and bodyText, depending // on the passed format. both will only be filled if format equals to "multipart" $filter = new Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput($_POST, Conjoon_Filter_Input::CONTEXT_CREATE); $data = $filter->getProcessedData(); } catch (Exception $e) { require_once 'Conjoon/Error.php'; $error = Conjoon_Error::fromFilter($filter, $e); $this->view->success = false; $this->view->error = $error->getDto(); $this->view->item = null; return; } // input filter does not work properly sometimes with refrenced data // check here for referencedData, throw an exception if not set if (!isset($data['referencedData']) || !is_array($data['referencedData'])) { throw new Exception("referencedData missing."); } /** * @see Conjoon_Modules_Groupware_Email_Address */ require_once 'Conjoon/Modules/Groupware/Email/Address.php'; /** * @see Conjoon_Modules_Groupware_Email_Draft */ require_once 'Conjoon/Modules/Groupware/Email/Draft.php'; /** * @see Conjoon_BeanContext_Inspector */ require_once 'Conjoon/BeanContext/Inspector.php'; $postedAttachments = $data['attachments']; $data['attachments'] = array(); $removeAttachmentIds = $data['removedAttachments']; unset($data['removedAttachments']); // create the message object here $to = array(); $cc = array(); $bcc = array(); foreach ($data['cc'] as $dcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dcc); $cc[] = $add; } foreach ($data['bcc'] as $dbcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dbcc); $bcc[] = $add; } foreach ($data['to'] as $dto) { $add = new Conjoon_Modules_Groupware_Email_Address($dto); $to[] = $add; } $data['cc'] = $cc; $data['to'] = $to; $data['bcc'] = $bcc; // get the specified account for the user /** * @see Conjoon_BeanContext_Decorator */ require_once 'Conjoon/BeanContext/Decorator.php'; /** * @see Conjoon_Keys */ require_once 'Conjoon/Keys.php'; $accountDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Account_Model_Account'); $auth = Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT); $userId = $auth->getIdentity()->getId(); $account = $accountDecorator->getAccountAsEntity($data['groupwareEmailAccountsId'], $userId); // no account found? if (!$account) { $this->view->error = $this->getErrorDto('Error while sending email', 'Could not find specified account.', Conjoon_Error::LEVEL_ERROR); $this->view->success = false; $this->view->item = null; return; } $message = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Draft', $data, true); $updateCache = false; // check whether we need to apply attachments for a previously saved // draft if ($message->getId() > 0 && !$this->isRemotePath($data['path'], $userId)) { $updateCache = true; /** * @see Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse */ require_once 'Conjoon/Modules/Groupware/Email/Attachment/Filter/AttachmentResponse.php'; $attDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Attachment_Model_Attachment', new Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse(array(), Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse::CONTEXT_RESPONSE)); $atts = $attDecorator->getAttachmentsForItemAsEntity($message->getId()); $message->setAttachments($atts); } /** * @see Conjoon_Modules_Groupware_Email_Sender */ require_once 'Conjoon/Modules/Groupware/Email/Sender.php'; try { $transport = $this->getTransportForAccount($account); $assembleInformation = Conjoon_Modules_Groupware_Email_Sender::getAssembledMail($message, $account, $postedAttachments, $removeAttachmentIds, $this->getCurrentAppUser()->getId(), $transport, $data['type']); $assembledMail = $assembleInformation['message']; $postedAttachments = $assembleInformation['postedAttachments']; $mail = Conjoon_Modules_Groupware_Email_Sender::send($assembledMail); } catch (Exception $e) { $errorMessage = $e->getMessage(); // check here if a message is set. We rely heavily on stream_socket_client // in Zend_Mail_Protocol_Abstract which may not set the error message all // the time. If no internet conn is available, the message will be missing // on windows systems, for example if ($errorMessage == "") { $errorMessage = "The message with the subject \"" . $message->getSubject() . "\" could not be sent. " . "Please check the internet connection of " . "the server this software runs on."; } $this->view->error = $this->getErrorDto('Error while sending email', $errorMessage, Conjoon_Error::LEVEL_ERROR); $this->view->success = false; $this->view->item = null; return; } // check here if the referenced data contains an IMAP message. // if this is the case, update the message with the \Answered // flag if applicable $referencedData = $message->getReferencedData(); $referencedRemoteItem = null; $contextReferencedItem = null; $isRemoteItemReferenced = false; // check if the mesage was loaded from a remote draft // if this is the case, remove the draft from the rmeote server $imapAccount = $message->getId() > 0 ? $this->isRemotePath($message->getPath(), $userId) : null; if ($message->getId() > 0 && $imapAccount) { $uId = $message->getId(); $path = $message->getPath(); /** * @see Conjoon_Text_Parser_Mail_MailboxFolderPathJsonParser */ require_once 'Conjoon/Text/Parser/Mail/MailboxFolderPathJsonParser.php'; $parser = new Conjoon_Text_Parser_Mail_MailboxFolderPathJsonParser(); $pathInfo = $parser->parse(json_encode($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 remote, where is the referenced mail stored? $globalName = $facade->getAssembledGlobalNameForAccountAndPath($imapAccount, $pathInfo['path']); /** * @see Conjoon_Modules_Groupware_Email_ImapHelper */ require_once 'Conjoon/Modules/Groupware/Email/ImapHelper.php'; /** * @see Conjoon_Mail_Storage_Imap */ require_once 'Conjoon/Mail/Storage/Imap.php'; $protocol = Conjoon_Modules_Groupware_Email_ImapHelper::reuseImapProtocolForAccount($imapAccount); $storage = new Conjoon_Mail_Storage_Imap($protocol); // get the number of the message by it's unique id $storage->selectFolder($globalName); $messageNumber = $storage->getNumberByUniqueId($uId); $storage->removeMessage($messageNumber); $storage->close(); } if (!empty($referencedData) && isset($referencedData['uId']) && $referencedData['uId'] > 0) { $uId = $referencedData['uId']; $referencedPath = $referencedData['path']; // 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(json_encode($referencedPath)); /** * @see Conjoon_Modules_Groupware_Email_Folder_Facade */ require_once 'Conjoon/Modules/Groupware/Email/Folder/Facade.php'; $facade = Conjoon_Modules_Groupware_Email_Folder_Facade::getInstance(); // get the account for the root folder first $imapAccount = $facade->getImapAccountForFolderIdAndUserId($pathInfo['rootId'], $userId); if ($imapAccount && !empty($pathInfo) && $facade->isRemoteFolder($pathInfo['rootId'])) { $isRemoteItemReferenced = true; // if remote, where is the referenced mail stored? $globalName = $facade->getAssembledGlobalNameForAccountAndPath($imapAccount, $pathInfo['path']); /** * @see Conjoon_Modules_Groupware_Email_ImapHelper */ require_once 'Conjoon/Modules/Groupware/Email/ImapHelper.php'; /** * @see Conjoon_Mail_Storage_Imap */ require_once 'Conjoon/Mail/Storage/Imap.php'; $protocol = Conjoon_Modules_Groupware_Email_ImapHelper::reuseImapProtocolForAccount($imapAccount); $storage = new Conjoon_Mail_Storage_Imap($protocol); // get the number of the message by it's unique id $storage->selectFolder($globalName); $messageNumber = $storage->getNumberByUniqueId($uId); $flags = array('\\Seen'); if ($data['type'] == 'reply' || $data['type'] == 'reply_all') { $flags = array('\\Seen', '\\Answered'); } else { if ($data['type'] == 'forward') { $flags = array('\\Seen', '$Forwarded'); } } $protocol->store($flags, $messageNumber, null, '+'); $referencedRemoteItem = $this->getSingleImapListItem($imapAccount, $userId, $messageNumber, $globalName); // force a reconnect if internal noop fails Conjoon_Modules_Groupware_Email_ImapHelper::reuseImapProtocolForAccount($imapAccount); } } $folderMappingError = null; if ($account->getProtocol() == 'IMAP') { /** * @see Conjoon_Modules_Groupware_Email_ImapHelper */ require_once 'Conjoon/Modules/Groupware/Email/ImapHelper.php'; /** * @see Zend_Registry */ require_once 'Zend/Registry.php'; /** *@see Conjoon_Keys */ require_once 'Conjoon/Keys.php'; $entityManager = Zend_Registry::get(Conjoon_Keys::DOCTRINE_ENTITY_MANAGER); $mailAccountRepository = $entityManager->getRepository('\\Conjoon\\Data\\Entity\\Mail\\DefaultMailAccountEntity'); $accEntity = $mailAccountRepository->findById($account->getId()); $mappings = $accEntity->getFolderMappings(); $globalName = ""; for ($i = 0, $len = count($mappings); $i < $len; $i++) { if ($mappings[$i]->getType() == 'SENT') { $globalName = $mappings[$i]->getGlobalName(); } } if ($globalName != "") { /** * @see Conjoon_Mail_Storage_Imap */ require_once 'Conjoon/Mail/Storage/Imap.php'; $protocol = Conjoon_Modules_Groupware_Email_ImapHelper::reuseImapProtocolForAccount($account->getDto()); $storage = new Conjoon_Mail_Storage_Imap($protocol); try { $storage->selectFolder($globalName); $response = $storage->appendMessage($mail->getSentHeaderText() . "\n\n" . $mail->getSentBodyText(), $globalName); $lastMessage = -1; $ret = null; if (is_array($response) && isset($response[0])) { $ret = explode(' ', $response[0]); } if (is_array($ret) && count($ret) == 2 && is_numeric($ret[0]) && trim(strtolower($ret[1])) == 'exists') { $lastMessage = $ret[0]; } if ($lastMessage == -1) { $lastMessage = $storage->countMessages(); } if ($lastMessage == -1) { throw new RuntimeException("Could not find message id."); } // immediately setting the \Seen flag does not seemt // to work. Do so by hand. $storage->setFlags($lastMessage, array('\\Seen')); } catch (\Exception $e) { $folderMappingError = true; } } else { $folderMappingError = true; } if ($folderMappingError) { $folderMappingError = $this->getErrorDto('Missing folder mapping', 'The email was sent, but a "sent" version could not be stored to the configured IMAP account. Make sure you have configured the folder mappings for this account properly.', Conjoon_Error::LEVEL_ERROR); } else { $item = $this->getSingleImapListItem($account->getDto(), $userId, $lastMessage, $globalName); } // check here if a remote item was referenced. // if this is not the case, get the local itemand update it's // references if (!$isRemoteItemReferenced && !$referencedRemoteItem && isset($referencedData) && isset($referencedData['uId']) && $referencedData['uId'] > 0) { $uId = $referencedData['uId']; $localFolder = $referencedData['path'][count($referencedData['path']) - 1]; /** * @see Conjoon_Modules_Groupware_Email_Item_Model_Item */ require_once 'Conjoon/Modules/Groupware/Email/Item/Model/Item.php'; $iModel = new Conjoon_Modules_Groupware_Email_Item_Model_Item(); $iModel->updateReferenceFromARemoteItem($uId, $localFolder, $userId, $data['type']); /** * @see Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse */ require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/ItemResponse.php'; // if the email was send successfully, save it into the db and // return the params savedId (id of the newly saved email) // and savedFolderId (id of the folder where the email was saved in) $itemDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Item_Model_Item', new Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse(array(), Conjoon_Filter_Input::CONTEXT_RESPONSE), false); $contextReferencedItem = $itemDecorator->getItemForUserAsDto($uId, $userId); } $this->view->error = null; $this->view->newVersion = $message->getId() > 0; if ($message->getId() > 0) { $this->view->previousId = $message->getId(); } $this->view->folderMappingError = $folderMappingError; $this->view->success = true; $this->view->item = isset($item) ? $item : null; $this->view->contextReferencedItem = $contextReferencedItem ? $contextReferencedItem : $referencedRemoteItem; return; } /** * @see Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse */ require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/ItemResponse.php'; // if the email was send successfully, save it into the db and // return the params savedId (id of the newly saved email) // and savedFolderId (id of the folder where the email was saved in) $itemDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Item_Model_Item', new Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse(array(), Conjoon_Filter_Input::CONTEXT_RESPONSE), false); $item = $itemDecorator->saveSentEmailAsDto($message, $account, $userId, $mail, $data['type'], $referencedRemoteItem ? -1 : $data['referencedData']['uId'], $postedAttachments, $removeAttachmentIds); if (!$item) { $this->view->error = $this->getErrorDto('Error while saving email', 'The email was sent, but it could not be stored into the database.', Conjoon_Error::LEVEL_ERROR); $this->view->success = false; $this->view->item = null; return; } if ($updateCache) { /** * @see Conjoon_Modules_Groupware_Email_Message_Facade */ require_once 'Conjoon/Modules/Groupware/Email/Message/Facade.php'; // update cache Conjoon_Modules_Groupware_Email_Message_Facade::getInstance()->removeMessageFromCache($item->id, $this->_helper->registryAccess()->getUserId(), $data['path']); } // if the sent email referenced an existing message, tr to fetch this message // and send it along as context-referenced item if (!$referencedRemoteItem) { $contextReferencedItem = $itemDecorator->getReferencedItemAsDto($item->id, $userId); } $this->view->error = null; $this->view->foldermappingError = $folderMappingError; $this->view->success = true; $this->view->item = $item; $this->view->contextReferencedItem = $referencedRemoteItem ? $referencedRemoteItem : (empty($contextReferencedItem) ? null : $contextReferencedItem); }