Exemplo n.º 1
0
 /**
  * Ensure everything works as expected.
  */
 public function testApply_legacy()
 {
     $applyTests = $this->getApplyTests();
     foreach ($applyTests as $test) {
         $source = $test['source'];
         $apply = $test['apply'];
         $result = $test['result'];
         \Conjoon_Util_Array::apply($source, $apply);
         foreach ($result as $key => $value) {
             $this->assertArrayHasKey($key, $source);
             $this->assertSame($value, $source[$key]);
         }
     }
 }
Exemplo n.º 2
0
 /**
  * Returns the meta data for the lob.
  * The following properties must exist in $data:
  * - path The complete path to the lob
  * - includeResource optional, if the lob should be returned as a string,
  * too
  *
  * @param array $data
  *
  * @return array An array with the following properties:
  *  - dirname
  *  - basename
  *  - extension
  *  - filename
  *  - resource with the plain content of the lob, if
  * includeResource was set to true
  * or null if the path was not valid
  *
  * @throws Conjoon_Data_Exception
  */
 public function getLobData(array $data)
 {
     Conjoon_Argument_Check::check(array('path' => array('type' => 'string')), $data);
     $path = $this->_sanitizePath($data['path']);
     if (!@file_exists($path)) {
         throw new Conjoon_Data_Exception("File \"{$path}\" does not seem to exist.");
     }
     if (@is_dir($path)) {
         throw new Conjoon_Data_Exception("Path \"{$path}\" seems to point to a directory.");
     }
     $lobData = array();
     Conjoon_Util_Array::apply($lobData, pathinfo($path));
     if (isset($data['includeResource']) && $data['includeResource']) {
         $fc = @file_get_contents($path);
         $lobData['resource'] = $fc !== false ? $fc : "";
         $fc = null;
     }
     return $lobData;
 }
 /**
  * A draft can be loaded from the database if an id was supplied
  * or filled with dummy data if no id was supplied. If no id was supplied,
  * the user wants to create a new email. In this case, the id defaults to
  * -1. If the user requests to save the draft later on, the id will be updated
  * to the value of the auto_increment field of the table.
  * Along with an id the application will need a folder_id so it can tell whether
  * an existing view has to be updated if this draft was edited and the folder
  * is currently visible.
  * Note, that getDraft will also be executed when the user wants to reply to
  * an email or forward an email. in this case, the id defaults to the email to
  * which the user wants to forward/ reply to.
  *
  * The method awaits 4 POST parameters:
  * id - the original message to reply to OR the id of the draft that is being
  * edited
  * type - the context the draft is in: can be either "new", "forward",
  *        "reply", "reply_all" or "edit"
  * name:    the name of an recipient to send this email to
  * address: the address of an recipient to send this email to. If that value is not
  *          empty. id will be set to -1 and type will be set to new. If address equals
  *          to name or if name is left empty, only the address will be used to send the
  *          email to. Address is given presedence in any case
  */
 public function getDraftAction()
 {
     if ($this->_helper->conjoonContext()->getCurrentContext() != self::CONTEXT_JSON) {
         /**
          * see Conjoon_Controller_Action_InvalidContextException
          */
         require_once 'Conjoon/Controller/Action/InvalidContextException.php';
         throw new Conjoon_Controller_Action_InvalidContextException("Invalid context for action, expected \"" . self::CONTEXT_JSON . "\", got \"" . $this->_helper->conjoonContext()->getCurrentContext() . "\"");
     }
     $path = $_POST['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($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 (!empty($pathInfo) && $facade->isRemoteFolder($pathInfo['rootId'])) {
         return $this->getDraftFromRemoteServer($_POST['id'], $path, $_POST['type']);
     }
     /**
      * @see Conjoon_Keys
      */
     require_once 'Conjoon/Keys.php';
     /**
      * @see Conjoon_BeanContext_Inspector
      */
     require_once 'Conjoon/BeanContext/Inspector.php';
     /**
      * @see Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse
      */
     require_once 'Conjoon/Modules/Groupware/Email/Draft/Filter/DraftResponse.php';
     /**
      * @see Conjoon_Modules_Groupware_Email_Account_Model_Account
      */
     require_once 'Conjoon/Modules/Groupware/Email/Account/Model/Account.php';
     /**
      * @see Conjoon_Util_Array
      */
     require_once 'Conjoon/Util/Array.php';
     $auth = Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT);
     $userId = $auth->getIdentity()->getId();
     $id = (int) $_POST['id'];
     $type = (string) $_POST['type'];
     $accountModel = new Conjoon_Modules_Groupware_Email_Account_Model_Account();
     // create a new draft so that the user is able to write an email from scratch!
     if ($id <= 0) {
         /**
          * @see Conjoon_Modules_Groupware_Email_Draft
          */
         require_once 'Conjoon/Modules/Groupware/Email/Draft.php';
         $standardId = $accountModel->getStandardAccountIdForUser($userId);
         if ($standardId == 0) {
             $this->view->error = $this->getErrorDto('Error while opening draft', 'Please configure an email account first.', Conjoon_Error::LEVEL_ERROR);
             $this->view->draft = null;
             $this->view->success = false;
             return;
         }
         $post = $_POST;
         Conjoon_Util_Array::apply($post, array('groupwareEmailAccountsId' => $standardId, 'groupwareEmailFoldersId' => -1));
         $draftFilter = new Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse($post, Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse::CONTEXT_NEW);
         $data = $draftFilter->getProcessedData();
         $draft = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Draft', $data);
         $this->view->success = true;
         $this->view->error = null;
         $this->view->draft = $draft->getDto();
         $this->view->type = $type;
         return;
     }
     // load an email to edit, to reply or to forward it
     /**
      * @see Conjoon_Modules_Groupware_Email_Draft_Model_Draft
      */
     require_once 'Conjoon/Modules/Groupware/Email/Draft/Model/Draft.php';
     $draftModel = new Conjoon_Modules_Groupware_Email_Draft_Model_Draft();
     $draftData = $draftModel->getDraft($id, $userId, $type);
     if (empty($draftData)) {
         $this->view->error = $this->getErrorDto('Error while opening draft', 'Could not find the referenced draft.', Conjoon_Error::LEVEL_ERROR);
         $this->view->draft = null;
         $this->view->success = false;
         return;
     }
     switch ($type) {
         case 'reply':
             $context = Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse::CONTEXT_REPLY;
             break;
         case 'reply_all':
             $context = Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse::CONTEXT_REPLY_ALL;
             break;
         case 'forward':
             $context = Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse::CONTEXT_FORWARD;
             break;
         case 'edit':
             $context = Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse::CONTEXT_EDIT;
             break;
         default:
             throw new Exception("Type {$type} not supported.");
             break;
     }
     Conjoon_Util_Array::camelizeKeys($draftData);
     $addresses = $accountModel->getEmailAddressesForUser($userId);
     $draftData['userEmailAddresses'] = $addresses;
     /**
      * @ticket CN-708
      * if context is not edit and equals to reply* or forward, read out the
      * "to" address and find the matching account we'll be using for setting as
      * account from which the mail gets edited
      */
     $matchingAccountId = -1;
     if ($context !== Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse::CONTEXT_EDIT) {
         $orgTo = $draftData['to'];
         $matchingAccountId = $this->guessMailAccountForAddress($orgTo);
         if ($matchingAccountId > -1) {
             $draftData['groupwareEmailAccountsId'] = $matchingAccountId;
         }
     }
     $draftFilter = new Conjoon_Modules_Groupware_Email_Draft_Filter_DraftResponse($draftData, $context);
     $data = $draftFilter->getProcessedData();
     $templateData = $data;
     // needed for draft forward because of Bean_Inspector
     unset($data['userEmailAddresses']);
     unset($data['from']);
     unset($data['replyTo']);
     if ($type == 'forward') {
         $data['to'] = array();
         $data['cc'] = array();
     }
     // convert email addresses
     /**
      * @see Conjoon_Modules_Groupware_Email_Address
      */
     require_once 'Conjoon/Modules/Groupware/Email/Address.php';
     $to = array();
     $cc = array();
     $bcc = array();
     foreach ($data['to'] as $add) {
         $to[] = new Conjoon_Modules_Groupware_Email_Address($add);
     }
     foreach ($data['cc'] as $add) {
         $cc[] = new Conjoon_Modules_Groupware_Email_Address($add);
     }
     foreach ($data['bcc'] as $add) {
         $bcc[] = new Conjoon_Modules_Groupware_Email_Address($add);
     }
     $data['to'] = $to;
     $data['cc'] = $cc;
     $data['bcc'] = $bcc;
     $draft = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Draft', $data)->getDto();
     if ($type == 'forward') {
         $applicationPath = $this->_helper->registryAccess()->getApplicationPath();
         /**
          * @see Conjoon_Text_PhpTemplate
          */
         require_once 'Conjoon/Text/PhpTemplate.php';
         /**
          * @see Conjoon_Filter_StringWrap
          */
         require_once 'Conjoon/Filter/StringWrap.php';
         /**
          * @see Zend_Filter_HtmlEntities
          */
         require_once 'Zend/Filter/HtmlEntities.php';
         $cfsw = new Conjoon_Filter_StringWrap('[Fwd: ', ']');
         $zfhe = new Zend_Filter_HtmlEntities(array('quotestyle' => ENT_COMPAT, 'charset' => 'UTF-8'));
         $draft->subject = $cfsw->filter($templateData['subject']);
         $templateData['subject'] = $zfhe->filter($templateData['subject']);
         $phpTemplate = new Conjoon_Text_PhpTemplate(array(Conjoon_Text_PhpTemplate::PATH => $applicationPath . '/templates/groupware/email/message.forward.phtml', Conjoon_Text_PhpTemplate::VARS => $templateData));
         $draft->contentTextPlain = $phpTemplate->getParsedTemplate();
     }
     $this->view->success = true;
     $this->view->error = null;
     $this->view->draft = $draft;
     $this->view->type = $type;
 }
Exemplo n.º 4
0
 /**
  * Creates a lob.
  * Additional parameters will be added to the array during processing,
  * such as the generated key for the lob.
  *
  * @param array $data An associative array with at least the following
  * key/value pairs:
  * - resource The resource to fetch the content from. This can either be
  * a native resource or a string. If $isPath is set to true, the string
  * will be treatened as a path and the contents from the file found under
  * this path will be read out/copied/moved.
  * @param bool $isPath Whether to treat "resource" as a file path.
  * @param bool $move if §isPath is set to true,
  *
  * @param bool $move
  *
  * @return array|null an array with the submitted data, along with additional
  * properties applied during runtime, or null on failure. The $result will be
  * stored in the variable $dbResult
  *
  * @throws Conjoon_Data_Exception
  */
 protected function _createLob(array &$data, $isPath = false, $move = false)
 {
     if (!isset($data['resource'])) {
         throw new Conjoon_Data_Exception("Property \"resource not available for \" _createLob.");
     }
     $resource = $data['resource'];
     $useFileSystem = $this->_isFileSystemUsedForLobs();
     $lobStorageBasePath = $this->_getLobStorageBasePath();
     $key = $this->_generateLobKey($data);
     $path = null;
     Conjoon_Util_Array::apply($data, array('key' => $key, 'lobStorageBasePath' => $lobStorageBasePath));
     // try to create the folders first if filestorage is used,
     // so we still have the db as a fallback
     if ($lobStorageBasePath !== null && $useFileSystem === true) {
         $storageContainer = $this->_generateStorageContainerString($data);
         Conjoon_Util_Array::apply($data, array('storageContainer' => $storageContainer));
         $path = $this->_createFolder($data);
     }
     // first off, create the needed data in the database
     // if path is null, the app is either configured not to use
     // the file system for storing lobs or soemthing went wrong
     // while trying to find the dir where to store the lob
     if ($path === null) {
         if (!is_resource($resource) && $isPath === true) {
             $result = $this->_addLobFromPathToDb($data);
             if ($move === true) {
                 $this->_fileLobAccess->deleteLobForId($resource);
             }
         } else {
             if (is_resource($resource)) {
                 $result = $this->_addLobFromResourceToDb($resource, $data);
             } else {
                 // string
                 $result = $this->_dbLobAccess->addLob($data);
             }
         }
         if ($result === null) {
             return null;
         }
         Conjoon_Util_Array::apply($data, array('dbResult' => $result));
         return $data;
     }
     // create needed data for storing file in file system
     $resource = $data['resource'];
     $data['resource'] = "";
     $id = (int) $this->_dbLobAccess->addLob($data);
     if ($id <= 0) {
         return null;
     }
     Conjoon_Util_Array::apply($data, array('id' => $id, 'resource' => $resource, 'dbResult' => $id));
     $file = $this->_generateFileNameStringForLob($data);
     $fileName = $path . '/' . $file;
     // does the file already exist?
     if (@file_exists($fileName)) {
         $this->_dbLobAccess->deleteLobForId($id);
         return null;
     }
     // and finally, add the file contents to the file system
     if (is_resource($resource)) {
         $res = $this->_fileLobAccess->addLobFromStream(array('path' => $fileName, 'resource' => $resource));
     } else {
         if ($isPath) {
             if ($move === true) {
                 $res = $this->_fileLobAccess->moveLob(array('from' => $resource, 'to' => $path, 'name' => $file));
             } else {
                 $res = $this->_fileLobAccess->copyLob(array('from' => $resource, 'to' => $path, 'name' => $file));
             }
         } else {
             $res = $this->_fileLobAccess->addLob(array('path' => $fileName, 'resource' => $resource));
         }
     }
     if ($res === null) {
         $this->_dbLobAccess->deleteLobForId($id);
         return null;
     }
     return $data;
 }
Exemplo n.º 5
0
 /**
  * Saves a sent email into the database.
  *
  * @param Conjoon_Modules_Groupware_Email_Draft $message
  * @param Conjoon_Modules_Groupware_Email_Account $account
  * @param integer $userId
  * @param Conjoon_Mail_Sent $mailSent
  * @param string $type
  * @param integer $referencesId The id of the email that was refernced sending this
  * message. This argument will only be taken into account if $type euqals to
  * reply or reply_all
  * @param array $postedAttachments
  * @param array $removeAttachmentIds
  *
  * @return array the data from groupware_email_item associated with
  * the newly saved entry
  */
 public function saveSentEmail(Conjoon_Modules_Groupware_Email_Draft $message, Conjoon_Modules_Groupware_Email_Account $account, $userId, Conjoon_Mail_Sent $mailSent, $type = "", $referencesId = -1, $postedAttachments = array(), $removeAttachmentIds = array())
 {
     $mail = $mailSent->getMailObject();
     $userId = (int) $userId;
     $accountId = (int) $account->getId();
     $messageId = (int) $message->getId();
     $referenceId = $referencesId <= 0 ? 0 : $referencesId;
     if ($userId <= 0 || $accountId <= 0) {
         return array();
     }
     $referencesModel = new Conjoon_Modules_Groupware_Email_Item_Model_References();
     $emailRecipientsFilter = new Conjoon_Filter_EmailRecipients();
     $emailRecipientsToStringFilter = new Conjoon_Filter_EmailRecipientsToString();
     $outboxModel = new Conjoon_Modules_Groupware_Email_Item_Model_Outbox();
     $folderModel = new Conjoon_Modules_Groupware_Email_Folder_Model_Folder();
     // first check the folder type of the email
     $folderId = $message->getGroupwareEmailFoldersId();
     $messageType = 'scratch';
     // negative/0, means the message was created from draft
     if ($folderId <= 0) {
         $messageType = 'scratch';
     } else {
         // anything else needs the meta info type fetched out of the folder model
         $metaInfo = $folderModel->getMetaInfo($folderId);
         switch ($metaInfo) {
             case Conjoon_Modules_Groupware_Email_Folder_Model_Folder::META_INFO_OUTBOX:
                 $messageType = 'outbox';
                 break;
             case Conjoon_Modules_Groupware_Email_Folder_Model_Folder::META_INFO_DRAFT:
                 $messageType = 'draft';
                 break;
                 // anything else is probably a reply or forward to an existing message in any other
                 // folder
             // anything else is probably a reply or forward to an existing message in any other
             // folder
             default:
                 $messageType = 'scratch';
                 break;
         }
     }
     // adjust the message type depending on the type
     if ($type == 'reply' || $type == 'reply_all' || $type == 'forward') {
         $messageType = 'scratch';
     }
     // prefill update/insert arrays
     $sentFolderId = $folderModel->getSentFolder($accountId, $userId);
     $date = new Zend_Date($mail->getDate(), Zend_Date::RFC_2822);
     $replyTo = (string) $mail->getReplyTo();
     $to = $message->getTo();
     $cc = $message->getCc();
     $bcc = $message->getBcc();
     $fromAddress = new Conjoon_Modules_Groupware_Email_Address(array($account->getAddress(), $account->getUserName()));
     $toString = array();
     foreach ($to as $recipient) {
         $toString[] = $recipient->__toString();
     }
     $toString = implode(', ', $toString);
     $ccString = array();
     foreach ($cc as $recipient) {
         $ccString[] = $recipient->__toString();
     }
     $ccString = implode(', ', $ccString);
     $bccString = array();
     foreach ($bcc as $recipient) {
         $bccString[] = $recipient->__toString();
     }
     $bccString = implode(', ', $bccString);
     $outboxUpdate = array('sent_timestamp' => time(), 'raw_header' => $mailSent->getSentHeaderText(), 'raw_body' => $mailSent->getSentBodyText(), 'groupware_email_accounts_id' => $message->getGroupwareEmailAccountsId());
     /**
      * @see Conjoon_Filter_DateToUtc
      */
     require_once 'Conjoon/Filter/DateToUtc.php';
     $filterToUtc = new Conjoon_Filter_DateToUtc();
     $itemUpdate = array('reply_to' => $replyTo, 'from' => $fromAddress->__toString(), 'recipients' => $emailRecipientsToStringFilter->filter($emailRecipientsFilter->filter(array($toString, $ccString, $bccString))), 'sender' => $emailRecipientsToStringFilter->filter($emailRecipientsFilter->filter(array($fromAddress->__toString()))), 'groupware_email_folders_id' => $sentFolderId, 'date' => $filterToUtc->filter($date->get(Zend_Date::ISO_8601)));
     switch ($messageType) {
         // if the message was sent from an opened draft or from the outbox,
         // we simply can create a new entry in the tables,
         // as if it was created from scratch
         // if, however, the email was sent from drafts, a user might have updated
         // the addresses, the subject, the email text and the attachments.
         // those fields have to be updated in the datastorage as well
         case 'draft':
             Conjoon_Util_Array::apply($itemUpdate, array('subject' => $message->getSubject(), 'to' => $toString, 'cc' => $ccString, 'bcc' => $bccString, 'content_text_plain' => $message->getContentTextPlain(), 'content_text_html' => $message->getContentTextHtml()));
             $this->saveAttachmentsForDraft($message, $postedAttachments, $removeAttachmentIds);
             // most simple: mesageType is outbox which means we have simply to update a few fields
         // most simple: mesageType is outbox which means we have simply to update a few fields
         case 'outbox':
             if ($messageId <= 0 || $sentFolderId == 0) {
                 return array();
             }
             // the message might have referenced an item when it was created.
             // look up entry in reference table and set this to is_pending = false
             $referencesWhere = $referencesModel->getAdapter()->quoteInto('groupware_email_items_id = ?', $messageId) . ' AND ' . $referencesModel->getAdapter()->quoteInto('user_id = ?', $userId);
             $referencesModel->update(array('is_pending' => 0), $referencesWhere);
             $outboxWhere = $outboxModel->getAdapter()->quoteInto('groupware_email_items_id = ?', $messageId);
             $outboxModel->update($outboxUpdate, $outboxWhere);
             $itemWhere = $this->getAdapter()->quoteInto('id = ?', $messageId);
             $this->update($itemUpdate, $itemWhere);
             return $this->getItemForUser($messageId, $userId);
             break;
             // if the message was created from scratch, i.e. has no id and no folderId,
             // save a fresh row into the tables groupware_email_items_id, groupware_email_items_flags,
             // groupware_email_items_outbox
         // if the message was created from scratch, i.e. has no id and no folderId,
         // save a fresh row into the tables groupware_email_items_id, groupware_email_items_flags,
         // groupware_email_items_outbox
         case 'scratch':
             Conjoon_Util_Array::apply($itemUpdate, array('subject' => $message->getSubject(), 'to' => $toString, 'cc' => $ccString, 'bcc' => $bccString, 'in_reply_to' => $message->getInReplyTo(), 'references' => $message->getReferences(), 'content_text_plain' => $message->getContentTextPlain(), 'content_text_html' => $message->getContentTextHtml()));
             $messageId = (int) $this->insert($itemUpdate);
             if ($messageId <= 0) {
                 return array();
             }
             $flagModel = new Conjoon_Modules_Groupware_Email_Item_Model_Flag();
             $referenceType = '';
             if (($type == Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_REPLY || $type == Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_REPLY_ALL || $type == Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_FORWARD) && $referenceId != 0) {
                 $referenceType = $type;
                 $referenceUpdate = array('groupware_email_items_id' => $messageId, 'user_id' => $userId, 'reference_items_id' => $referenceId, 'reference_type' => $referenceType);
                 $referencesModel->insert($referenceUpdate);
             }
             $flagUpdate = array('groupware_email_items_id' => $messageId, 'user_id' => $userId, 'is_read' => 1, 'is_spam' => 0, 'is_deleted' => 0);
             $flagModel->insert($flagUpdate);
             Conjoon_Util_Array::apply($outboxUpdate, array('groupware_email_items_id' => $messageId));
             $outboxModel->insert($outboxUpdate);
             $message->setId($messageId);
             $this->saveAttachmentsForDraft($message, $postedAttachments, $removeAttachmentIds);
             return $this->getItemForUser($messageId, $userId);
             break;
     }
     return null;
 }