/** * Helper for setting the properties of an Conjoon_BeanContext-object. * Will throw an exception if the method associated with the property was * not found, or any exception that was thrown by the accessor-method * of <tt>$object</tt>. * The method assumes that <tt>property</tt> is already a valid property name * according to <tt>Conjoon_BeanContext</tt>-conventions. * * @param Object $object The instance to set the property for. Must be of type * <tt>Conjoon_BeanContext</tt> * @param string $property The property name that is about to be set. * @param mixed $value The value to pass as the argument to the * setter-method of <tt>$property</tt> * @param boolean $ignoreMissing when set to true, the method will not throw an error * if the * * @throws Exception * @see Conjoon_BeanContext */ private static function setProperty($object, $property, $value, $ignoreMissing = false) { $method = self::getAccessorForProperty($object, $property, self::SETTER); if ($method === null && $ignoreMissing == false) { throw new Conjoon_BeanContext_Exception("Setter for {$property} not found."); } else { if ($method === null) { return; } } if (is_array($value) && strpos($method, 'add') === 0) { $reflM = new ReflectionMethod($object, $method); $params = $reflM->getParameters(); $cls = $params[0]->getClass()->getName(); /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; for ($i = 0, $len = count($value); $i < $len; $i++) { Conjoon_Util_Array::camelizeKeys($value[$i]); $val = Conjoon_BeanContext_Inspector::create($cls, $value[$i], true); $object->{$method}($val); } } else { $object->{$method}($value); } }
/** * Tries to cast a numeric/associative array into it's representant * entity model as defined in $_entity. * * @param array $data The array data, if numeric, a numeric array * will be returned, with values of the type $className. If an * associative array was submitted, a single object of the type * $className will be returned. * * @return mixed Either an array of objects or a single object. */ protected final function _cast($values, $type) { if ($values instanceof Zend_Db_Table_Rowset_Abstract || $values instanceof Zend_Db_Table_Row_Abstract || is_object($values) && method_exists($values, 'toArray')) { $values = $values->toArray(); } if (!is_array($values) || $type == self::TYPE_ARRAY) { return $values; } $len = count($values); if ($len == 0) { return array(); } $entity = $this->_entity; // simple check to determine if we have a assoc or numeric // array if (!Conjoon_Util_Array::isAssociative($values)) { $data = array(); $TYPE_DTO = $type == self::TYPE_DTO; for ($i = 0; $i < $len; $i++) { Conjoon_Util_Array::camelizeKeys($values[$i]); if ($this->_filter) { $values[$i] = $this->_filter->setData($values[$i])->getProcessedData(); } $data[] = Conjoon_BeanContext_Inspector::create($entity, $values[$i], !$this->_strict); if ($TYPE_DTO) { $data[$i] = $data[$i]->getDto(); if ($this->_filter) { $vv =& $values[$i]; $dd =& $data[$i]; $props = get_class_vars(get_class($data[$i])); foreach ($props as $propname => $propvalue) { if (!array_key_exists($propname, $vv)) { unset($dd->{$propname}); } } } } } return $data; } else { Conjoon_Util_Array::camelizeKeys($values); if ($this->_filter) { $values = $this->_filter->setData($values)->getProcessedData(); } $data = Conjoon_BeanContext_Inspector::create($entity, $values, !$this->_strict); if ($type == self::TYPE_DTO) { return $data->getDto(); } return $data; } }
/** * Transforms the specified array to a list of * Conjoon_Modules_Default_Registry_Dto * * @param array $entries * @return array */ private function _toDtos(array $entries) { /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; /** * @see Conjoon_Modules_Default_Registry_Dto */ require_once 'Conjoon/Modules/Default/Registry/Dto.php'; $dtos = array(); foreach ($entries as $key => $value) { $dto = new Conjoon_Modules_Default_Registry_Dto(); $dto->id = $value['id']; $dto->parentId = $value['parent_id']; $dto->key = $value['key']; $myValues = array(); for ($i = 0, $len = count($value['values']); $i < $len; $i++) { $mv =& $value['values'][$i]; Conjoon_Util_Array::camelizeKeys($mv); $myValues[] = $mv; } $dto->values = $myValues; $dtos[] = $dto; } return $dtos; }
/** * 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; }
/** * Bulk sends emails. Awaits the parameter ids as a numeric array with the ids of * the emails which should get send. * */ public function bulkSendAction() { /*@REMOVE@*/ if (!$this->_helper->connectionCheck()) { /** * @see Conjoon_Error_Factory */ require_once 'Conjoon/Error/Factory.php'; $this->view->success = false; $this->view->sentItems = array(); $this->view->error = null; $this->view->contextReferencedItems = array(); $this->view->error = Conjoon_Error_Factory::createError("Unexpected connection failure while trying to bulk-send emails. " . "Please try again.", Conjoon_Error::LEVEL_WARNING, Conjoon_Error::DATA)->getDto(); return; } /*@REMOVE@*/ $toSend = $_POST['ids']; if ($this->_helper->conjoonContext()->getCurrentContext() == self::CONTEXT_JSON) { require_once 'Zend/Json.php'; $toSend = Zend_Json::decode($toSend, Zend_Json::TYPE_ARRAY); } $date = null; if (isset($_POST['date'])) { require_once 'Conjoon/Filter/DateIso8601.php'; $dateFilter = new Conjoon_Filter_DateIso8601(); $date = $dateFilter->filter((int) $_POST['date']); } /** * @see Conjoon_Filter_EmailRecipients */ require_once 'Conjoon/Filter/EmailRecipients.php'; /** * @see Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse */ require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/ItemResponse.php'; /** * @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'; /** * @see Conjoon_BeanContext_Decorator */ require_once 'Conjoon/BeanContext/Decorator.php'; /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; /** * @see Conjoon_Keys */ require_once 'Conjoon/Keys.php'; /** * @see Conjoon_Modules_Groupware_Email_Draft_Model_Draft */ require_once 'Conjoon/Modules/Groupware/Email/Draft/Model/Draft.php'; /** * @see Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput */ require_once 'Conjoon/Modules/Groupware/Email/Draft/Filter/DraftInput.php'; /** * @see Conjoon_Modules_Groupware_Email_Sender */ require_once 'Conjoon/Modules/Groupware/Email/Sender.php'; $auth = Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT); $userId = $auth->getIdentity()->getId(); $draftFilter = new Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput(array(), Conjoon_Filter_Input::CONTEXT_CREATE); $draftModel = new Conjoon_Modules_Groupware_Email_Draft_Model_Draft(); $accountDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Account_Model_Account'); $recipientsFilter = new Conjoon_Filter_EmailRecipients(); $newVersions = array(); $sendItems = array(); $contextReferencedItems = array(); $errors = array(); foreach ($toSend as $pathInfo) { $remoteInfo = array(); $id = $pathInfo['id']; $path = $pathInfo['path']; $account = null; $remoteAttachments = array(); // check if path is remote! $isRemote = $this->isRemotePath($path, $userId); if ($isRemote) { $rawDraft = $this->getRawImapMessage($id, $path); if (empty($rawDraft)) { continue; } //we have to post the existing attachments of the remote draft // again when assembling the message to send. // Otherwise the sender would not know which attachments should get send // along with the message $remoteAttachments = $rawDraft['attachments']; foreach ($remoteAttachments as &$remoteAttachment) { $remoteAttachment['metaType'] = 'emailAttachment'; $remoteAttachment['name'] = $remoteAttachment['fileName']; } $remoteInfo = array('uid' => $id, 'account' => $isRemote, 'path' => $path); $rawDraft['groupwareEmailAccountsId'] = $isRemote->id; $account = $accountDecorator->getAccountAsEntity($rawDraft['groupwareEmailAccountsId'], $userId); } else { $rawDraft = $draftModel->getDraft($id, $userId); $account = $accountDecorator->getAccountAsEntity($rawDraft['groupware_email_accounts_id'], $userId); } // no account found? if (!$account) { /** * @todo think about using the standard account as a fallback or use at last * an error message to inform the user that the account used to write this email * is not available anymore */ continue; } $id = (int) $id; if ($id <= 0) { continue; } if (empty($rawDraft)) { continue; } Conjoon_Util_Array::camelizeKeys($rawDraft); $rawDraft['to'] = $recipientsFilter->filter($rawDraft['to']); $rawDraft['cc'] = $recipientsFilter->filter($rawDraft['cc']); $rawDraft['bcc'] = $recipientsFilter->filter($rawDraft['bcc']); // create the message object here $to = array(); $cc = array(); $bcc = array(); foreach ($rawDraft['cc'] as $dcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dcc); $cc[] = $add; } foreach ($rawDraft['bcc'] as $dbcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dbcc); $bcc[] = $add; } foreach ($rawDraft['to'] as $dto) { $add = new Conjoon_Modules_Groupware_Email_Address($dto); $to[] = $add; } $rawDraft['to'] = $to; $rawDraft['cc'] = $cc; $rawDraft['bcc'] = $bcc; $message = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Draft', $rawDraft, true); if ($date !== null) { $message->setDate($date); } try { $transport = $this->getTransportForAccount($account); $assembleInformation = Conjoon_Modules_Groupware_Email_Sender::getAssembledMail($message, $account, $remoteAttachments, array(), $this->getCurrentAppUser()->getId(), $transport); $assembledMail = $assembleInformation['message']; $postedAttachments = $assembleInformation['postedAttachments']; $mail = Conjoon_Modules_Groupware_Email_Sender::send($assembledMail); } catch (Exception $e) { $errors[] = array('subject' => $message->getSubject(), 'accountName' => $account->getName(), 'reason' => $e->getMessage()); continue; } if ($isRemote) { /** * @see Conjoon_Modules_Groupware_Email_ImapHelper */ require_once 'Conjoon/Modules/Groupware/Email/ImapHelper.php'; $uId = $remoteInfo['uid']; $account = $remoteInfo['account']; $path = $remoteInfo['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($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(); // get the account for the root folder first $imapAccount = $facade->getImapAccountForFolderIdAndUserId($pathInfo['rootId'], $userId); if ($imapAccount && !empty($pathInfo) && $facade->isRemoteFolder($pathInfo['rootId'])) { // 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); // move from sent folder $sentGlobalName = $this->getGlobalNameForFolderType($imapAccount, 'SENT'); if (!$sentGlobalName) { continue; } $storage->copyMessage($messageNumber, $sentGlobalName); $storage->selectFolder($sentGlobalName); $newMessageNumber = $storage->countMessages(); $storage->selectFolder($globalName); $storage->removeMessage($storage->getNumberByUniqueId($uId)); $storage->close(); } // put email into sent folder $protocol = Conjoon_Modules_Groupware_Email_ImapHelper::reuseImapProtocolForAccount($imapAccount); $storage = new Conjoon_Mail_Storage_Imap($protocol); // read out single item $item = $this->getSingleImapListItem($account, $userId, $newMessageNumber, $sentGlobalName); $newVersions[$uId] = $item['id']; $sendItems[] = $item; } else { // 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, ''); if (!$item) { continue; } $sendItems[] = $item; $cri = $itemDecorator->getReferencedItemAsDto($item->id, $userId); if (!empty($cri)) { $contextReferencedItems[] = $cri; } } } if (!empty($errors)) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; $m = array(); $m[] = "One or more messages could not be sent:"; for ($i = 0, $len = count($errors); $i < $len; $i++) { $m[] = "Message " . ($i + 1) . ":"; $m[] = "Subject: \"" . $errors[$i]['subject'] . "\""; $m[] = "Account: " . $errors[$i]['accountName']; $m[] = "Failure reason: " . $errors[$i]['reason']; } $errorMessage = implode("\n", $m); $error = new Conjoon_Error(); $error->setLevel(Conjoon_Error::LEVEL_WARNING); $error->setType(Conjoon_Error::DATA); $error->setMessage($errorMessage); } $this->view->newVersions = $newVersions; $this->view->success = true; $this->view->sentItems = $sendItems; $this->view->error = isset($error) ? $error->getDto() : null; $this->view->contextReferencedItems = $contextReferencedItems; }