/**
  * 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'];
 }
Esempio n. 3
0
 /**
  * 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);
 }
Esempio n. 4
0
 /**
  * Ensure everything works as expected.
  */
 public function testApply_legacy()
 {
     $applyTests = $this->getApplyTests();
     foreach ($applyTests as $test) {
         $source = $test['source'];
         $apply = $test['apply'];
         $result = $test['result'];
         \Conjoon_Util_Array::apply($source, $apply);
         foreach ($result as $key => $value) {
             $this->assertArrayHasKey($key, $source);
             $this->assertSame($value, $source[$key]);
         }
     }
 }
Esempio n. 5
0
 /**
  * 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);
     }
 }
Esempio n. 6
0
 /**
  * Returns the meta data for the lob.
  * The following properties must exist in $data:
  * - path The complete path to the lob
  * - includeResource optional, if the lob should be returned as a string,
  * too
  *
  * @param array $data
  *
  * @return array An array with the following properties:
  *  - dirname
  *  - basename
  *  - extension
  *  - filename
  *  - resource with the plain content of the lob, if
  * includeResource was set to true
  * or null if the path was not valid
  *
  * @throws Conjoon_Data_Exception
  */
 public function getLobData(array $data)
 {
     Conjoon_Argument_Check::check(array('path' => array('type' => 'string')), $data);
     $path = $this->_sanitizePath($data['path']);
     if (!@file_exists($path)) {
         throw new Conjoon_Data_Exception("File \"{$path}\" does not seem to exist.");
     }
     if (@is_dir($path)) {
         throw new Conjoon_Data_Exception("Path \"{$path}\" seems to point to a directory.");
     }
     $lobData = array();
     Conjoon_Util_Array::apply($lobData, pathinfo($path));
     if (isset($data['includeResource']) && $data['includeResource']) {
         $fc = @file_get_contents($path);
         $lobData['resource'] = $fc !== false ? $fc : "";
         $fc = null;
     }
     return $lobData;
 }
Esempio n. 7
0
 /**
  * Creates a lob.
  * Additional parameters will be added to the array during processing,
  * such as the generated key for the lob.
  *
  * @param array $data An associative array with at least the following
  * key/value pairs:
  * - resource The resource to fetch the content from. This can either be
  * a native resource or a string. If $isPath is set to true, the string
  * will be treatened as a path and the contents from the file found under
  * this path will be read out/copied/moved.
  * @param bool $isPath Whether to treat "resource" as a file path.
  * @param bool $move if §isPath is set to true,
  *
  * @param bool $move
  *
  * @return array|null an array with the submitted data, along with additional
  * properties applied during runtime, or null on failure. The $result will be
  * stored in the variable $dbResult
  *
  * @throws Conjoon_Data_Exception
  */
 protected function _createLob(array &$data, $isPath = false, $move = false)
 {
     if (!isset($data['resource'])) {
         throw new Conjoon_Data_Exception("Property \"resource not available for \" _createLob.");
     }
     $resource = $data['resource'];
     $useFileSystem = $this->_isFileSystemUsedForLobs();
     $lobStorageBasePath = $this->_getLobStorageBasePath();
     $key = $this->_generateLobKey($data);
     $path = null;
     Conjoon_Util_Array::apply($data, array('key' => $key, 'lobStorageBasePath' => $lobStorageBasePath));
     // try to create the folders first if filestorage is used,
     // so we still have the db as a fallback
     if ($lobStorageBasePath !== null && $useFileSystem === true) {
         $storageContainer = $this->_generateStorageContainerString($data);
         Conjoon_Util_Array::apply($data, array('storageContainer' => $storageContainer));
         $path = $this->_createFolder($data);
     }
     // first off, create the needed data in the database
     // if path is null, the app is either configured not to use
     // the file system for storing lobs or soemthing went wrong
     // while trying to find the dir where to store the lob
     if ($path === null) {
         if (!is_resource($resource) && $isPath === true) {
             $result = $this->_addLobFromPathToDb($data);
             if ($move === true) {
                 $this->_fileLobAccess->deleteLobForId($resource);
             }
         } else {
             if (is_resource($resource)) {
                 $result = $this->_addLobFromResourceToDb($resource, $data);
             } else {
                 // string
                 $result = $this->_dbLobAccess->addLob($data);
             }
         }
         if ($result === null) {
             return null;
         }
         Conjoon_Util_Array::apply($data, array('dbResult' => $result));
         return $data;
     }
     // create needed data for storing file in file system
     $resource = $data['resource'];
     $data['resource'] = "";
     $id = (int) $this->_dbLobAccess->addLob($data);
     if ($id <= 0) {
         return null;
     }
     Conjoon_Util_Array::apply($data, array('id' => $id, 'resource' => $resource, 'dbResult' => $id));
     $file = $this->_generateFileNameStringForLob($data);
     $fileName = $path . '/' . $file;
     // does the file already exist?
     if (@file_exists($fileName)) {
         $this->_dbLobAccess->deleteLobForId($id);
         return null;
     }
     // and finally, add the file contents to the file system
     if (is_resource($resource)) {
         $res = $this->_fileLobAccess->addLobFromStream(array('path' => $fileName, 'resource' => $resource));
     } else {
         if ($isPath) {
             if ($move === true) {
                 $res = $this->_fileLobAccess->moveLob(array('from' => $resource, 'to' => $path, 'name' => $file));
             } else {
                 $res = $this->_fileLobAccess->copyLob(array('from' => $resource, 'to' => $path, 'name' => $file));
             }
         } else {
             $res = $this->_fileLobAccess->addLob(array('path' => $fileName, 'resource' => $resource));
         }
     }
     if ($res === null) {
         $this->_dbLobAccess->deleteLobForId($id);
         return null;
     }
     return $data;
 }
Esempio n. 8
0
 /**
  * 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;
     }
 }
Esempio n. 9
0
 /**
  * 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;
 }
Esempio n. 12
0
 /**
  * Saves a sent email into the database.
  *
  * @param Conjoon_Modules_Groupware_Email_Draft $message
  * @param Conjoon_Modules_Groupware_Email_Account $account
  * @param integer $userId
  * @param Conjoon_Mail_Sent $mailSent
  * @param string $type
  * @param integer $referencesId The id of the email that was refernced sending this
  * message. This argument will only be taken into account if $type euqals to
  * reply or reply_all
  * @param array $postedAttachments
  * @param array $removeAttachmentIds
  *
  * @return array the data from groupware_email_item associated with
  * the newly saved entry
  */
 public function saveSentEmail(Conjoon_Modules_Groupware_Email_Draft $message, Conjoon_Modules_Groupware_Email_Account $account, $userId, Conjoon_Mail_Sent $mailSent, $type = "", $referencesId = -1, $postedAttachments = array(), $removeAttachmentIds = array())
 {
     $mail = $mailSent->getMailObject();
     $userId = (int) $userId;
     $accountId = (int) $account->getId();
     $messageId = (int) $message->getId();
     $referenceId = $referencesId <= 0 ? 0 : $referencesId;
     if ($userId <= 0 || $accountId <= 0) {
         return array();
     }
     $referencesModel = new Conjoon_Modules_Groupware_Email_Item_Model_References();
     $emailRecipientsFilter = new Conjoon_Filter_EmailRecipients();
     $emailRecipientsToStringFilter = new Conjoon_Filter_EmailRecipientsToString();
     $outboxModel = new Conjoon_Modules_Groupware_Email_Item_Model_Outbox();
     $folderModel = new Conjoon_Modules_Groupware_Email_Folder_Model_Folder();
     // first check the folder type of the email
     $folderId = $message->getGroupwareEmailFoldersId();
     $messageType = 'scratch';
     // negative/0, means the message was created from draft
     if ($folderId <= 0) {
         $messageType = 'scratch';
     } else {
         // anything else needs the meta info type fetched out of the folder model
         $metaInfo = $folderModel->getMetaInfo($folderId);
         switch ($metaInfo) {
             case Conjoon_Modules_Groupware_Email_Folder_Model_Folder::META_INFO_OUTBOX:
                 $messageType = 'outbox';
                 break;
             case Conjoon_Modules_Groupware_Email_Folder_Model_Folder::META_INFO_DRAFT:
                 $messageType = 'draft';
                 break;
                 // anything else is probably a reply or forward to an existing message in any other
                 // folder
             // anything else is probably a reply or forward to an existing message in any other
             // folder
             default:
                 $messageType = 'scratch';
                 break;
         }
     }
     // adjust the message type depending on the type
     if ($type == 'reply' || $type == 'reply_all' || $type == 'forward') {
         $messageType = 'scratch';
     }
     // prefill update/insert arrays
     $sentFolderId = $folderModel->getSentFolder($accountId, $userId);
     $date = new Zend_Date($mail->getDate(), Zend_Date::RFC_2822);
     $replyTo = (string) $mail->getReplyTo();
     $to = $message->getTo();
     $cc = $message->getCc();
     $bcc = $message->getBcc();
     $fromAddress = new Conjoon_Modules_Groupware_Email_Address(array($account->getAddress(), $account->getUserName()));
     $toString = array();
     foreach ($to as $recipient) {
         $toString[] = $recipient->__toString();
     }
     $toString = implode(', ', $toString);
     $ccString = array();
     foreach ($cc as $recipient) {
         $ccString[] = $recipient->__toString();
     }
     $ccString = implode(', ', $ccString);
     $bccString = array();
     foreach ($bcc as $recipient) {
         $bccString[] = $recipient->__toString();
     }
     $bccString = implode(', ', $bccString);
     $outboxUpdate = array('sent_timestamp' => time(), 'raw_header' => $mailSent->getSentHeaderText(), 'raw_body' => $mailSent->getSentBodyText(), 'groupware_email_accounts_id' => $message->getGroupwareEmailAccountsId());
     /**
      * @see Conjoon_Filter_DateToUtc
      */
     require_once 'Conjoon/Filter/DateToUtc.php';
     $filterToUtc = new Conjoon_Filter_DateToUtc();
     $itemUpdate = array('reply_to' => $replyTo, 'from' => $fromAddress->__toString(), 'recipients' => $emailRecipientsToStringFilter->filter($emailRecipientsFilter->filter(array($toString, $ccString, $bccString))), 'sender' => $emailRecipientsToStringFilter->filter($emailRecipientsFilter->filter(array($fromAddress->__toString()))), 'groupware_email_folders_id' => $sentFolderId, 'date' => $filterToUtc->filter($date->get(Zend_Date::ISO_8601)));
     switch ($messageType) {
         // if the message was sent from an opened draft or from the outbox,
         // we simply can create a new entry in the tables,
         // as if it was created from scratch
         // if, however, the email was sent from drafts, a user might have updated
         // the addresses, the subject, the email text and the attachments.
         // those fields have to be updated in the datastorage as well
         case 'draft':
             Conjoon_Util_Array::apply($itemUpdate, array('subject' => $message->getSubject(), 'to' => $toString, 'cc' => $ccString, 'bcc' => $bccString, 'content_text_plain' => $message->getContentTextPlain(), 'content_text_html' => $message->getContentTextHtml()));
             $this->saveAttachmentsForDraft($message, $postedAttachments, $removeAttachmentIds);
             // most simple: mesageType is outbox which means we have simply to update a few fields
         // most simple: mesageType is outbox which means we have simply to update a few fields
         case 'outbox':
             if ($messageId <= 0 || $sentFolderId == 0) {
                 return array();
             }
             // the message might have referenced an item when it was created.
             // look up entry in reference table and set this to is_pending = false
             $referencesWhere = $referencesModel->getAdapter()->quoteInto('groupware_email_items_id = ?', $messageId) . ' AND ' . $referencesModel->getAdapter()->quoteInto('user_id = ?', $userId);
             $referencesModel->update(array('is_pending' => 0), $referencesWhere);
             $outboxWhere = $outboxModel->getAdapter()->quoteInto('groupware_email_items_id = ?', $messageId);
             $outboxModel->update($outboxUpdate, $outboxWhere);
             $itemWhere = $this->getAdapter()->quoteInto('id = ?', $messageId);
             $this->update($itemUpdate, $itemWhere);
             return $this->getItemForUser($messageId, $userId);
             break;
             // if the message was created from scratch, i.e. has no id and no folderId,
             // save a fresh row into the tables groupware_email_items_id, groupware_email_items_flags,
             // groupware_email_items_outbox
         // if the message was created from scratch, i.e. has no id and no folderId,
         // save a fresh row into the tables groupware_email_items_id, groupware_email_items_flags,
         // groupware_email_items_outbox
         case 'scratch':
             Conjoon_Util_Array::apply($itemUpdate, array('subject' => $message->getSubject(), 'to' => $toString, 'cc' => $ccString, 'bcc' => $bccString, 'in_reply_to' => $message->getInReplyTo(), 'references' => $message->getReferences(), 'content_text_plain' => $message->getContentTextPlain(), 'content_text_html' => $message->getContentTextHtml()));
             $messageId = (int) $this->insert($itemUpdate);
             if ($messageId <= 0) {
                 return array();
             }
             $flagModel = new Conjoon_Modules_Groupware_Email_Item_Model_Flag();
             $referenceType = '';
             if (($type == Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_REPLY || $type == Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_REPLY_ALL || $type == Conjoon_Modules_Groupware_Email_Keys::REFERENCE_TYPE_FORWARD) && $referenceId != 0) {
                 $referenceType = $type;
                 $referenceUpdate = array('groupware_email_items_id' => $messageId, 'user_id' => $userId, 'reference_items_id' => $referenceId, 'reference_type' => $referenceType);
                 $referencesModel->insert($referenceUpdate);
             }
             $flagUpdate = array('groupware_email_items_id' => $messageId, 'user_id' => $userId, 'is_read' => 1, 'is_spam' => 0, 'is_deleted' => 0);
             $flagModel->insert($flagUpdate);
             Conjoon_Util_Array::apply($outboxUpdate, array('groupware_email_items_id' => $messageId));
             $outboxModel->insert($outboxUpdate);
             $message->setId($messageId);
             $this->saveAttachmentsForDraft($message, $postedAttachments, $removeAttachmentIds);
             return $this->getItemForUser($messageId, $userId);
             break;
     }
     return null;
 }
Esempio n. 13
0
 /**
  * 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;
 }
Esempio n. 14
0
 /**
  * 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;
 }
Esempio n. 15
0
 /**
  * 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;
 }