/** * Defined by Zend_Filter_Interface * * * @param mixed $value * @return integer */ public function filter($value) { if ($this->_root != null) { if (!array_key_exists(0, $value)) { return $value; } if (!array_key_exists($this->_root, $value[0])) { return $value; } $value = $value[0][$this->_root]; } if (!is_array($value)) { return $value; } /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; if (isset($value[0]) && is_array($value[0]) && count($value) == 1 && !Conjoon_Util_Array::isAssociative($value[0])) { return $value[0]; } if (Conjoon_Util_Array::isAssociative($value)) { return array($value); } return $value; }
public function __construct($options = array()) { $this->_options = $options; /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; Conjoon_Util_Array::applyIf($this->_options, array('addSlashes' => true, 'useQuoting' => true)); $this->_addSlashes = $this->_options['addSlashes']; $this->_useQuoting = $this->_options['useQuoting']; }
/** * Refreshes the parameter list for the specified request. * * @param Zend_Controller_Request_Abstract $request * @param Array $params */ protected function _applyParams(Zend_Controller_Request_Abstract $request, array $data) { $rData = empty($data['data']) ? array() : $data['data']; if (!Conjoon_Util_Array::isAssociative($rData)) { $request->setParam('data', $rData); } else { $request->setParams($rData); } unset($data['data']); $request->setParam($this->_config['extParameter'], $data); }
/** * 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]); } } }
/** * 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); } }
/** * 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; }
/** * 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; }
/** * 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; } }
/** * Imports and adds the items for the requested feed uri and adds them * to the account specified in $accountId if they do not already exist. * The account's lastUpdated property will also be set, and the item lists * cache will be cleaned, if feed items have been actually added. * * * @param integer $accountId * @param integer $userId * @param boolean $useReaderCache * @param boolean $useConditionalGet * * @return array Returns an array with the recently added * Conjoon_Modules_Groupware_Feeds_Item_Dto * * @throws Exception */ public function importAndAddFeedItems($accountId, $userId, $useReaderCache = false, $useConditionalGet = false) { $accountId = (int) $accountId; $userId = (int) $userId; if ($accountId <= 0 || $userId <= 0) { throw new InvalidArgumentException("Invalid argument supplied, accountId was \"{$accountId}\", " . "userId was \"{$userId}\""); } $accountDto = $this->_getAccountFacade()->getAccount($accountId, $userId); $uri = $accountDto->uri; $requestTimeout = $accountDto->requestTimeout; /** * @see Conjoon_Modules_Groupware_Feeds_ImportHelper */ require_once 'Conjoon/Modules/Groupware/Feeds/ImportHelper.php'; // get the feeds metadata try { $import = Conjoon_Modules_Groupware_Feeds_ImportHelper::importFeedItems($uri, $requestTimeout, $useReaderCache, $useConditionalGet); } catch (Exception $e) { Conjoon_Log::log(get_class($this) . "::importAndAddFeedItems could not import " . "feed items from {$uri}: \"" . get_class($e) . "\" - \"" . $e->getMessage() . "\"", Zend_Log::INFO); // return an empty array, do not delete cache for the account and do not // update last_updated timestamp! return array(); } /** * @see Conjoon_Modules_Groupware_Feeds_Item_Filter_Item */ require_once 'Conjoon/Modules/Groupware/Feeds/Item/Filter/Item.php'; $filter = new Conjoon_Modules_Groupware_Feeds_Item_Filter_Item(array(), Conjoon_Filter_Input::CONTEXT_CREATE); $itemResponseFilter = new Conjoon_Modules_Groupware_Feeds_Item_Filter_Item(array(), Conjoon_Filter_Input::CONTEXT_RESPONSE); /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; /** * @see Conjoon_BeanContext_Inspector */ require_once 'Conjoon/BeanContext/Inspector.php'; $added = array(); $cCache = false; foreach ($import as $item) { $normalized = Conjoon_Modules_Groupware_Feeds_ImportHelper::normalizeFeedItem($item); $normalized['groupwareFeedsAccountsId'] = $accountId; $filter->setData($normalized); try { $fillIn = $filter->getProcessedData(); } catch (Zend_Filter_Exception $e) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; Conjoon_Log::log(Conjoon_Error::fromFilter($filter, $e), Zend_Log::ERR); continue; } $dtoData = $fillIn; Conjoon_Util_Array::underscoreKeys($fillIn); $isAdded = $this->_addItemIfNotExists($fillIn, $accountId, false); if ($isAdded > 0) { $cCache = true; $dtoData['id'] = $isAdded; $dtoData['name'] = $accountDto->name; $itemResponseFilter->setData($dtoData); $dtoData = $itemResponseFilter->getProcessedData(); $added[] = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Feeds_Item', $dtoData)->getDto(); } } if ($cCache) { $this->_removeListCacheForAccountIds(array($accountId)); } $this->_getAccountFacade()->setLastUpdated(array($accountId), time()); return $added; }
/** * 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; }
/** * This action will update email accounts according to the POST params * that come along with the request. * Depending of the current context the action was called, the format of the * POST params will differ: For json, it will be an array holding json-encoded parameters. * Despite all different formats the POST params may come in, each request sends * values for 'updated' and 'deleted' accounts: 'deleted' as an array, holding all * ids that should become deleted, and 'updated' an array holding information about * the records that get edited, represented by specific associative array, representing * the fields of the record. * The view will await values assigned to 'updated_failed' and 'deleted_failed', whereas * 'deleted_failed' is an array containing all ids that couldn't be deleted, and * 'updated_failed' an array containing the records (in associative array notation) * that could not be updated. * * Note: If any error in the user-input was detected, no update-action will happen, but * deltes may already have been submitted to the underlying datastore. * The first error found in the passed data will be returned as an error of the type * Conjoon_Error_Form, containing the fields that where errorneous. * */ public function updateEmailAccountsAction() { require_once 'Conjoon/Modules/Groupware/Email/Account/Filter/Account.php'; require_once 'Conjoon/Util/Array.php'; require_once 'Conjoon/Modules/Groupware/Email/Account/Model/Account.php'; $toDelete = array(); $toUpdate = array(); $deletedFailed = array(); $updatedFailed = array(); $model = new Conjoon_Modules_Groupware_Email_Account_Model_Account(); $data = array(); $error = null; if ($this->_helper->conjoonContext()->getCurrentContext() == self::CONTEXT_JSON) { require_once 'Zend/Json.php'; $toDelete = Zend_Json::decode($_POST['deleted'], Zend_Json::TYPE_ARRAY); $toUpdate = Zend_Json::decode($_POST['updated'], Zend_Json::TYPE_ARRAY); } $numToUpdate = count($toUpdate); $numToDelete = count($toDelete); if ($numToUpdate != 0 || $numToDelete != 0) { /** * @see Conjoon_Builder_Factory */ require_once 'Conjoon/Builder/Factory.php'; Conjoon_Builder_Factory::getBuilder(Conjoon_Keys::CACHE_EMAIL_ACCOUNTS, Zend_Registry::get(Conjoon_Keys::REGISTRY_CONFIG_OBJECT)->toArray())->cleanCacheForTags(array('userId' => Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT)->getIdentity()->getId())); } $userId = $this->_helper->registryAccess()->getUserId(); for ($i = 0; $i < $numToDelete; $i++) { $affected = $model->deleteAccount($toDelete[$i], $userId); if ($affected == 0) { $deletedFailed[] = $toDelete[$i]; } } $folderMappingData = array(); for ($i = 0; $i < $numToUpdate; $i++) { $_ = $toUpdate[$i]; $folderMappingData[$toUpdate[$i]['id']] = $toUpdate[$i]['folderMappings']; $filter = new Conjoon_Modules_Groupware_Email_Account_Filter_Account($_, Conjoon_Filter_Input::CONTEXT_UPDATE); try { $data[$i] = $filter->getProcessedData(); Conjoon_Util_Array::underscoreKeys($data[$i]); } catch (Zend_Filter_Exception $e) { require_once 'Conjoon/Error.php'; $error = Conjoon_Error::fromFilter($filter, $e); $this->view->success = false; $this->view->updatedFailed = array($_['id']); $this->view->deletedFailed = $deletedFailed; $this->view->error = $error->getDto(); return; } } $createdLocalRootMailFolders = array(); $removedLocalRootMailFolders = array(); /** * @see Conjoon_BeanContext_Decorator */ require_once 'Conjoon/BeanContext/Decorator.php'; $decoratedFolderModel = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Folder_Model_Folder', null, false); $decoratedAccountModel = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Account_Model_Account'); /** * @see Conjoon_Modules_Groupware_Email_Folder_Model_Folder */ require_once 'Conjoon/Modules/Groupware/Email/Folder/Model/Folder.php'; $folderModel = new Conjoon_Modules_Groupware_Email_Folder_Model_Folder(); /** * @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(); for ($i = 0, $len = count($data); $i < $len; $i++) { $id = $data[$i]['id']; unset($data[$i]['id']); // check here for duplicates $duplicates = $model->getAccountWithNameForUser($data[$i]['name'], $userId); $affected = 0; if (!empty($duplicates)) { for ($a = 0, $lena = count($duplicates); $a < $lena; $a++) { if ($duplicates[$a]['id'] != $id) { $affected = -1; break; } } } if ($affected != -1) { $affected = $model->updateAccount($id, $data[$i]); $entityManager = Zend_Registry::get(Conjoon_Keys::DOCTRINE_ENTITY_MANAGER); // update folderMappings if (isset($folderMappingData[$id])) { $fmRep = $entityManager->getRepository('\\Conjoon\\Data\\Entity\\Mail\\DefaultFolderMappingEntity'); for ($u = 0, $lenu = count($folderMappingData[$id]); $u < $lenu; $u++) { if (isset($folderMappingData[$id][$u]['id']) && empty($folderMappingData[$id][$u]['path'])) { $updEnt = $fmRep->findById($folderMappingData[$id][$u]['id']); $updEnt->setGlobalName(""); $fmRep->register($updEnt); } else { if (isset($folderMappingData[$id][$u]['id']) && !empty($folderMappingData[$id][$u]['path'])) { /** * @see \Conjoon\Data\Entity\Mail\DefaultFolderMappingEntity */ require_once 'Conjoon/Data/Entity/Mail/DefaultFolderMappingEntity.php'; /** * @see Conjoon_Modules_Groupware_Email_ImapHelper */ require_once 'Conjoon/Modules/Groupware/Email/ImapHelper.php'; $accDto = $decoratedAccountModel->getAccountAsDto($id, $userId); $delim = Conjoon_Modules_Groupware_Email_ImapHelper::getFolderDelimiterForImapAccount($accDto); $p = $folderMappingData[$id][$u]['path']; array_shift($p); array_shift($p); $globalName = implode($delim, $p); $updEnt = $fmRep->findById($folderMappingData[$id][$u]['id']); $updEnt->setGlobalName($globalName); $fmRep->register($updEnt); continue; } } } $fmRep->flush(); } // take care of folder heirarchies if ($affected != -1) { /** * @todo Facade */ $hasSeparateFolderHierarchy = array_key_exists('has_separate_folder_hierarchy', $data[$i]) ? (bool) (int) $data[$i]['has_separate_folder_hierarchy'] : null; // get org protocol of account so it cannot be changed from // the outside $orgAccount = $model->getAccount($id, $userId); $orgProtocol = $orgAccount['protocol']; if ($hasSeparateFolderHierarchy !== null && strtolower($orgProtocol) !== 'imap') { // the original folder ids, before remapping occures $oldAccountFolderIds = $foldersAccounts->getFolderIdsForAccountId($id); // read out folder base data of folder for associated account $rootFolderBaseData = $decoratedFolderModel->getAnyRootMailFolderBaseDataAsDto($id, $userId); if (!$rootFolderBaseData) { throw new RuntimeException("No root folder base data available."); } if (!$hasSeparateFolderHierarchy) { // do nothing if type is already accounts_root and // separateFolderHierarchy = false is submitted; // but if the type is root and the folderHierarchy // (i.e. "root) should be removed, // we need to switch from root to accounts_root if ($rootFolderBaseData->type == 'root') { // check first if accounts_root exist! $accountsRootFolderId = $folderModel->getAccountsRootMailFolderBaseData($userId); // accounts root not yet existing if (!$accountsRootFolderId) { $folderModel->createFolderBaseHierarchyAndMapAccountIdForUserId($id, $userId); } else { $newFolderIds = $folderModel->getFoldersForAccountsRoot($userId); // accounts root already existing. // remove the root and remap to accounts_root foreach ($oldAccountFolderIds as $oldFolderId) { $folderModel->deleteFolder($oldFolderId, $userId, false); } $removedLocalRootMailFolders[$id] = $rootFolderBaseData; $foldersAccounts->mapFolderIdsToAccountId($newFolderIds, $id); } $createdLocalRootMailFolders[$id] = $decoratedFolderModel->getAnyRootMailFolderBaseDataAsDto($id, $userId); } } else { // do nothing if the type is already root which means // there already exists a separate folder hierarchy // if the type is accounts_root, we need to switch // to a root hierarchy if ($rootFolderBaseData->type == 'accounts_root') { // remove old mappings $foldersAccounts->deleteForAccountId($id); $folderModel->createFolderHierarchyAndMapAccountIdForUserId($id, $userId, $data[$i]['name']); $createdLocalRootMailFolders[$id] = $decoratedFolderModel->getAnyRootMailFolderBaseDataAsDto($id, $userId); } } } } } if ($affected == -1) { $updatedFailed[] = $id; } } $this->view->success = empty($updatedFailed) ? true : false; $this->view->updatedFailed = $updatedFailed; $this->view->deletedFailed = $deletedFailed; $this->view->error = null; $this->view->createdLocalRootMailFolders = $createdLocalRootMailFolders; $this->view->removedLocalRootMailFolders = $removedLocalRootMailFolders; }
/** * 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; }
/** * 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; }
/** * Updates a single account with the data from $data for the specified * $userId. * * @param integer $accountId the id of the account to update. * @param Array $data * @param integer $userId * * @return boolean true, if updating the account was successfull, otherwise * false * * @throws Exception */ public function updateAccount($accountId, array $data, $userId) { $accountId = (int) $accountId; $userId = (int) $userId; if ($userId <= 0 || $accountId <= 0) { throw new InvalidArgumentException("Invalid argument supplied, userId was \"{$userId}\", " . "accountId was \"{$accountId}\""); } $filter = $this->_getUpdateAccountFilter(); $filter->setData($data); try { $data = $filter->getProcessedData(); } catch (Zend_Filter_Exception $e) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; Conjoon_Log::log(Conjoon_Error::fromFilter($filter, $e), Zend_Log::ERR); return false; } if (array_key_exists('id', $data)) { unset($data['id']); } /** * @see Conjoon_Util_Array */ require_once 'Conjoon/Util/Array.php'; Conjoon_Util_Array::underscoreKeys($data); $affected = $this->_getAccountModel()->updateAccount($accountId, $data); if ($affected === true) { $this->_getBuilder()->remove(array('accountId' => $accountId)); $this->_getListBuilder()->cleanCacheForTags(array('userId' => $userId)); } return $affected === true ? true : false; }
/** * Saves the email and it's attachments. Uses the default db adapter as * configured by the application. If an exception occurs, the exception's * message will be stored in an array (together with other exceptions that * may have occured) and returned later on. Any db operation that failed will * be rolled back. * * @param array $emailItem An associative array with the data to insert into the * different tables. All attachments will be stored in the key/value pair "attachments", * which is itself a numeric array * * @return mixed Return the id of the last inserted email item, or an * error message if an error occured. */ private function _saveEmail(array $emailItem) { $filterAttachment = $this->_filterAttachment; $filterFlag = $this->_filterFlag; $filterItem = $this->_filterItem; $filterInbox = $this->_filterInbox; $modelAttachment = $this->_modelAttachment; $modelFlag = $this->_modelFlag; $modelItem = $this->_modelItem; $modelInbox = $this->_modelInbox; $dbAdapter = Zend_Db_Table::getDefaultAdapter(); if (!$this->_maxAllowedPacket) { $config = Zend_Registry::get(Conjoon_Keys::REGISTRY_CONFIG_OBJECT); $this->_maxAllowedPacket = $config->database->variables->max_allowed_packet; if (!$this->_maxAllowedPacket) { $this->_maxAllowedPacket = Conjoon_Db_Util::getMaxAllowedPacket($dbAdapter); } } $this->_setPlainFromHtml($emailItem); // filter and insert into groupware_email_items $filterItem->setData($emailItem); $itemData = $filterItem->getProcessedData(); if ($this->_maxAllowedPacket < strlen($emailItem['rawBody'])) { return 'Could not save message with subject "' . $itemData['subject'] . '" - message is larger than available packet size (' . $this->_maxAllowedPacket . ' bytes).'; } $dbAdapter->beginTransaction(); $currFilter = null; try { Conjoon_Util_Array::underscoreKeys($itemData); try { $id = (int) $modelItem->insert($itemData); } catch (Zend_Db_Statement_Exception $zdse) { // in very rare cases, there are 4-byte characters in a utf-8 // string, and mysql cannot handle them right since we use // utf-8 collations. We'll strip those 4-byte characters away. // see CN-619 $content = $itemData['content_text_plain']; $i = 0; $len = strlen($content); $fourByteDetected = false; while ($i < $len) { $ord = ord($content[$i]); switch (true) { case $ord <= 127: $i += 1; break; case $ord < 224: $i += 2; break; case $ord < 240: $i += 3; break; default: $fourByteDetected = true; $content = substr($content, 0, $i) . substr($content, $i + 4); $len -= 4; break; } } if ($fourByteDetected === true) { $lastResortData = $emailItem; $lastResortData['contentTextPlain'] = $content; $filterItem->setData($lastResortData); $lastResortItemData = $filterItem->getProcessedData(); Conjoon_Util_Array::underscoreKeys($lastResortItemData); $id = (int) $modelItem->insert($lastResortItemData); /** * @see Conjoon_Log */ require_once 'Conjoon/Log.php'; Conjoon_Log::log("Detected 4-byte character in content_text_plain for " . "Email message with id {$id}", Zend_Log::NOTICE); } } if ($id <= 0) { return null; } // assign needed (reference) keys $emailItem['isRead'] = 0; $emailItem['id'] = $id; $emailItem['groupwareEmailItemsId'] = $id; // filter and insert into groupware_email_items_inbox $currFilter = $filterInbox; $filterInbox->setData($emailItem); $itemData = $filterInbox->getProcessedData(); Conjoon_Util_Array::underscoreKeys($itemData); $modelInbox->addInboxData($itemData); // filter and insert into groupware_email_items_flag $currFilter = $filterFlag; $filterFlag->setData($emailItem); $itemData = $filterFlag->getProcessedData(); Conjoon_Util_Array::underscoreKeys($itemData); $modelFlag->insert($itemData); // loop through attachments and insert into groupware_email_items_attachments $attachmentCount = count($emailItem['attachments']); $currFilter = $filterAttachment; for ($i = 0; $i < $attachmentCount; $i++) { $emailItem['attachments'][$i]['groupwareEmailItemsId'] = $id; $filterAttachment->setData($emailItem['attachments'][$i]); $itemData = $filterAttachment->getProcessedData(); Conjoon_Util_Array::underscoreKeys($itemData); $modelAttachment->addAttachmentForItem($itemData, $id); } $dbAdapter->commit(); return $id; } catch (Exception $e) { if ($e instanceof Zend_Filter_Exception) { $error = Conjoon_Error::fromFilter($currFilter, $e); $error = $error->getMessage(); } else { $error = $e->getMessage(); } try { $dbAdapter->rollBack(); } catch (Exception $m) { $error .= '; ' . $m->getMessage(); } return $error; } }
/** * 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; }