/** * Returns a textual representation of the current object. * * @return string */ public function __toString() { $parts = array(); foreach ($this->fields as $field => $messages) { $parts[] = '"' . $field . '" - [' . implode(';', $messages) . ']'; } return 'fields: ' . implode(' - ', $parts) . ', ' . parent::__toString(); }
/** * Creates a Conjoon_Error object based on the passed arguments and * return the error object. * * @param string $message * @param string $level * @param string $code * @param string $file * @param string $line * * @return Conjoon_Error */ public static function createError($message = "[no message]", $level = null, $type = null, $code = null, $file = null, $line = null) { if ($level === null) { $level = Conjoon_Error::LEVEL_ERROR; } if ($type === null) { $type = Conjoon_Error::UNKNOWN; } $error = new Conjoon_Error(); $error->setMessage($message); $error->setLevel($level); $error->setType($type); $error->setCode($code); $error->setFile($file); $error->setLine($line); return $error; }
public function processAction() { require_once 'Conjoon/Auth/Adapter/Db.php'; /** * @todo Filter username and password! */ $username = $this->_getParam('username'); $password = $this->_getParam('password'); $rememberMe = (bool) $this->_getParam('rememberMe'); $lastUserRequest = (int) $this->_getParam('lastUserRequest'); // Special case - the app was started and the user wants to re-login // since his session was lost. Check if the user object as returned by the // data storage has a property lastLogin which may not be greater than // the "lastUserRequest"-parameter - if that is teh case, most likely another // user has logged in so the user has to completely restart the application - // a redirect to the base url will happen if ($lastUserRequest) { /** * @see Conjoon_Modules_Default_User_Model_User */ require_once 'Conjoon/Modules/Default/User/Model/User.php'; $userTable = new Conjoon_Modules_Default_User_Model_User(); /** * @see Conjoon_BeanContext_Decorator */ require_once 'Conjoon/BeanContext/Decorator.php'; $decorator = new Conjoon_BeanContext_Decorator($userTable); $userDto = $decorator->getUserForUserNameCredentialsAsDto($username, md5($password)); if ($userDto && $lastUserRequest <= $userDto->lastLogin) { // special case - send an auth token failure with the response $this->_response->setHttpResponseCode(401); /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; $error = new Conjoon_Error(); $error->setCode(-1); $error->setLevel(Conjoon_Error::LEVEL_ERROR); $error->setFile(__FILE__); $error->setLine(__LINE__); $error->setMessage("Someone has signed in with your user credentials. Please sign in again."); $error->setType(Conjoon_Error::TOKEN_FAILURE); $this->view->tokenFailure = true; /** * @todo create filter */ unset($userDto->authToken); $this->view->user = $userDto; $this->view->success = false; $this->view->error = $error->getDto(); return; } } $auth = Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT); $authAdapter = new Conjoon_Auth_Adapter_Db(array('username' => $username, 'password' => $password, 'remember_me' => $rememberMe)); // if the result is valid, the return value of the adapter will // be stored automatically in the supplied storage object // from the auth object $result = $auth->authenticate($authAdapter); if ($result->isValid()) { $user = $result->getIdentity(); if ($rememberMe && $user->getRememberMeToken() != null) { $this->setAutoLoginCookies(md5($user->getUserName()), $user->getRememberMeToken(), time() + 2592000); } $this->view->success = true; } else { $this->view->error = 'Wrong username or password'; $this->view->success = false; } }
/** * 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 outbox folder of the user. */ public function moveToOutboxAction() { /** * @see Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput */ require_once 'Conjoon/Modules/Groupware/Email/Draft/Filter/DraftInput.php'; $data = array(); try { // the filter will transform the "message" into bodyHtml and bodyText, depending // on the passed format. both will only be filled if format equals to "multipart" $filter = new Conjoon_Modules_Groupware_Email_Draft_Filter_DraftInput($_POST, Conjoon_Filter_Input::CONTEXT_CREATE); $data = $filter->getProcessedData(); $postedPath = $data['path']; } catch (Exception $e) { require_once 'Conjoon/Error.php'; $error = Conjoon_Error::fromFilter($filter, $e); $this->view->success = false; $this->view->error = $error->getDto(); $this->view->item = null; return; } /** * @see Conjoon_Modules_Groupware_Email_Address */ require_once 'Conjoon/Modules/Groupware/Email/Address.php'; /** * @see Conjoon_Modules_Groupware_Email_Draft */ require_once 'Conjoon/Modules/Groupware/Email/Draft.php'; /** * @see Conjoon_BeanContext_Inspector */ require_once 'Conjoon/BeanContext/Inspector.php'; // create the message object here $to = array(); $cc = array(); $bcc = array(); $postedAttachments = $data['attachments']; $data['attachments'] = array(); $removeAttachmentIds = $data['removedAttachments']; unset($data['removedAttachments']); foreach ($data['cc'] as $dcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dcc); $cc[] = $add; } foreach ($data['bcc'] as $dbcc) { $add = new Conjoon_Modules_Groupware_Email_Address($dbcc); $bcc[] = $add; } foreach ($data['to'] as $dto) { $add = new Conjoon_Modules_Groupware_Email_Address($dto); $to[] = $add; } $data['cc'] = $cc; $data['to'] = $to; $data['bcc'] = $bcc; // get the specified account for the user require_once 'Conjoon/BeanContext/Decorator.php'; require_once 'Conjoon/Keys.php'; $accountDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Account_Model_Account'); $auth = Zend_Registry::get(Conjoon_Keys::REGISTRY_AUTH_OBJECT); $userId = $auth->getIdentity()->getId(); $account = $accountDecorator->getAccountAsEntity($data['groupwareEmailAccountsId'], $userId); // no account found? if (!$account) { $this->view->error = $this->getErrorDto('Error while moving email to the outbox folder', 'Could not find specified account.', Conjoon_Error::LEVEL_ERROR); $this->view->success = false; $this->view->item = null; return; } $draft = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Draft', $data, true); if ($account->getProtocol() == 'IMAP') { return $this->moveImapToOutbox($account, $draft, $userId, $postedAttachments, $removeAttachmentIds); } $draft = Conjoon_BeanContext_Inspector::create('Conjoon_Modules_Groupware_Email_Draft', $data, true); $updateCache = false; // check whether we need to apply attachments for a previously saved // draft if ($draft->getId() > 0) { $updateCache = true; /** * @see Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse */ require_once 'Conjoon/Modules/Groupware/Email/Attachment/Filter/AttachmentResponse.php'; $attDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Attachment_Model_Attachment', new Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse(array(), Conjoon_Modules_Groupware_Email_Attachment_Filter_AttachmentResponse::CONTEXT_RESPONSE)); $atts = $attDecorator->getAttachmentsForItemAsEntity($draft->getId()); $draft->setAttachments($atts); } /** * @see Conjoon_BeanContext_Decorator */ require_once 'Conjoon/BeanContext/Decorator.php'; /** * @see Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse */ require_once 'Conjoon/Modules/Groupware/Email/Item/Filter/ItemResponse.php'; $itemDecorator = new Conjoon_BeanContext_Decorator('Conjoon_Modules_Groupware_Email_Item_Model_Item', new Conjoon_Modules_Groupware_Email_Item_Filter_ItemResponse(array(), Conjoon_Filter_Input::CONTEXT_RESPONSE), false); $item = $itemDecorator->moveDraftToOutboxAsDto($draft, $account, $userId, $data['type'], $data['referencesId'], $postedAttachments, $removeAttachmentIds); if (!$item) { $this->view->error = $this->getErrorDto('Error while saving email', 'The email could not be stored into the database.', Conjoon_Error::LEVEL_ERROR); $this->view->success = false; $this->view->item = null; return; } if ($updateCache) { /** * @see Conjoon_Modules_Groupware_Email_Message_Facade */ require_once 'Conjoon/Modules/Groupware/Email/Message/Facade.php'; // update cache Conjoon_Modules_Groupware_Email_Message_Facade::getInstance()->removeMessageFromCache($item->id, $this->_helper->registryAccess()->getUserId(), $postedPath); } $this->view->error = null; $this->view->success = true; $this->view->item = $item; }
/** * 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; }
/** * Transforms an array of exceptions to an array that can be easily handled * by the frontend. * The following keys are available: * * success: always set to false * error : either an array of Conjoon_ErrorDto's, or a single object of the * type Conjoon_ErrorDto * * @param Array $exceptions * * @return Array */ public static function transformExceptions(array $exceptions = array()) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; $exList = array(); if (count($exceptions) > 1) { for ($i = 0, $len = count($exceptions); $i < $len; $i++) { $ex = Conjoon_Error::fromException($exceptions[$i]); $exList[] = $ex->getDto(); } } else { $exception = Conjoon_Error::fromException($exceptions[0]); $exList = $exception->getDto(); } return array('success' => false, 'error' => $exList); }
/** * Sets the specified keys in $data to theri mapped values. * * @param array $data A numeric array with associative entries, i.e. * [[ 'key' => '/somekey/anotherkey', 'value' => 1]] * @param integer $userId The id of the user for which the entries should * be set. If those entries do not already exist for the specified * userId, this entries will be created. * * @return array Returns an associative array with the following keys: * - updated: A list of keys that were actually updated * - failed: list with keys that could not be updated * * @throws InvalidArgumentException throws an InvalidArgumentException if * the specified $userId was noit valid * or Conjoon_Filter_Exception if the submitted data could not be sanitized */ public function setEntriesFromDataForUserId(array $data, $userId) { if ($userId <= 0) { throw new InvalidArgumentException("Invalid argument supplied for userId - was \"{$userId}\""); } $filter = $this->_getUpdateEntriesFilter(); $sanitized = array(); try { for ($i = 0, $len = count($data); $i < $len; $i++) { $filter->setData($data[$i]); $sanitized[] = $filter->getProcessedData(); } } catch (Zend_Filter_Exception $e) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; $error = Conjoon_Error::fromFilter($filter, $e); /** * @see Conjoon_Filter_Exception */ require_once 'Conjoon/Filter/Exception.php'; throw new Conjoon_Filter_Exception($error->getMessage()); } $registry = $this->getRegistryForUserId($userId, false); $updated = array(); $failed = array(); for ($i = 0, $len = count($sanitized); $i < $len; $i++) { $failed[$sanitized[$i]['key']] = true; } for ($i = 0, $len = count($sanitized); $i < $len; $i++) { $key = $sanitized[$i]['key']; $value = $sanitized[$i]['value']; $keys = explode('/', $key); $valueName = array_pop($keys); $keys = implode('/', $keys); $path = $this->_pathToIndex($keys, $registry); if (!empty($path)) { $parent = $registry[$path[count($path) - 1]]; $valueConfig = $parent['values']; $registryId = $parent['id']; for ($a = 0, $lena = count($valueConfig); $a < $lena; $a++) { if ($valueConfig[$a]['is_editable'] && $valueConfig[$a]['name'] == $valueName) { $type = $valueConfig[$a]['type']; switch ($type) { case 'STRING': $value = (string) $value; break; case 'BOOLEAN': $value = (int) (bool) $value; break; case 'INTEGER': $value = (int) $value; break; case 'FLOAT': $value = (double) $value; break; } $succ = $this->_getRegistryValuesModel()->updateValueForUser($registryId, $valueName, $value, $type, $userId); if ($succ) { $updated[] = $key; unset($failed[$key]); } } } } } return array('updated' => $updated, 'failed' => array_keys($failed)); }
/** * 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; }
public function preDispatch() { if (!$this->getRequest()->isDispatched()) { return; } $action = $this->getRequest()->getActionName(); $class = get_class($this->getActionController()); if (!isset($this->_filterKeys[$class][$action])) { return; } $filter = $this->_getFilter($this->_filterKeys[$class][$action]); $actionController = $this->getActionController(); $data = $this->getRequest()->getParams(); if (isset($this->_extractFromExtDirect[$class][$action])) { /** * @see Conjoon_Keys */ require_once 'Conjoon/Keys.php'; try { $extRequest = Zend_Registry::get(Conjoon_Keys::EXT_REQUEST_OBJECT); } catch (Zend_Exception $e) { $extRequest = null; } if ($extRequest && $extRequest->isExtRequest()) { $data = $this->getRequest()->getParam('data'); $data = $data[0]; } } $filter->setData($data); try { $filteredData = $filter->getProcessedData(); } catch (Zend_Filter_Exception $e) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; $error = Conjoon_Error::fromFilter($filter, $e); /** * @see Conjoon_Filter_Exception */ require_once 'Conjoon/Filter/Exception.php'; throw new Conjoon_Filter_Exception($error->getMessage()); } foreach ($filteredData as $key => $value) { $this->getRequest()->setParam($key, $value); } }
/** * Renames the folder with the specified it to the specified value. * Post vars: * id : the id of the folder that gets renamed * name : the new name of the node * parentId : the id of the current parent folder * path : the path of this node in the tree. This is relevant for * IMAP mailboxes which get renamed */ public function renameFolderAction() { /** * @see Conjoon_Modules_Groupware_Email_Folder_Facade */ require_once 'Conjoon/Modules/Groupware/Email/Folder/Facade.php'; $facade = Conjoon_Modules_Groupware_Email_Folder_Facade::getInstance(); /** * @see Conjoon_Text_Parser_Mail_MailboxFolderPathJsonParser */ require_once 'Conjoon/Text/Parser/Mail/MailboxFolderPathJsonParser.php'; $parser = new Conjoon_Text_Parser_Mail_MailboxFolderPathJsonParser(); try { $pathParts = $parser->parse($this->_request->getParam('path')); } catch (Conjoon_Text_Parser_Exception $e) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; $error = Conjoon_Error::fromException($e); $this->view->success = false; $this->view->error = $error->getDto(); return; } $name = $this->_request->getParam('name'); $userId = $this->_helper->registryAccess->getUserId(); try { $folder = $facade->renameFolderForPathAndUserId($name, $pathParts, $userId); if ($folder === false) { /** * @see Conjoon_Error_Factory */ require_once 'Conjoon/Error/Factory.php'; $error = Conjoon_Error_Factory::createError("Could not rename the specified folder.", Conjoon_Error::LEVEL_WARNING)->getDto(); $this->view->success = false; $this->view->error = $error; return; } } catch (Exception $e) { /** * @see Conjoon_Error */ require_once 'Conjoon/Error.php'; $this->view->success = true; $this->view->error = Conjoon_Error::fromException($e)->getDto(); return; } $this->view->success = true; $this->view->error = null; $this->view->folder = $folder; }