/**
  * Saves a draft into the outbox folder of the user.
  */
 public function moveToOutboxAction()
 {
     /**
      * @see Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput
      */
     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();
         $postedPath = $data['path'];
     } 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 moving email to the outbox folder', '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);
     if ($account->getProtocol() == 'IMAP') {
         return $this->moveImapToOutbox($account, $draft, $userId, $postedAttachments, $removeAttachmentIds);
     }
     $draft = 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 ($draft->getId() > 0) {
         $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($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';
     $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->moveDraftToOutboxAsDto($draft, $account, $userId, $data['type'], $data['referencesId'], $postedAttachments, $removeAttachmentIds);
     if (!$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;
     }
     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(), $postedPath);
     }
     $this->view->error = null;
     $this->view->success = true;
     $this->view->item = $item;
 }
 /**
  * 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);
 }