/** * Search for records matching given filter * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param Tinebase_Model_Pagination $_pagination * @param array|string|boolean $_cols columns to get, * per default / use self::IDCOL or TRUE to get only ids * @return Tinebase_Record_RecordSet|array */ public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Model_Pagination $_pagination = NULL, $_cols = '*') { $filters = $_filter->getFilterObjects(); // TODO: implement this folder filter // $folderFilter = new Felamimail_Model_FolderFilter(array( // array('field' => 'account_id', 'operator' => 'in', 'value' => $accounts->getArrayOfIds()), // array('field' => 'localname', 'operator' => 'equals', 'value' => 'INBOX') // )); foreach ($filters as $filter) { switch ($filter->getField()) { case 'account_id': $accountId = $filter->getValue(); break; case 'parent': $globalName = $filter->getValue(); $parent = true; break; case 'id': $felamimailAccount = Felamimail_Controller_Account::getInstance()->search()->toArray(); $accountId = $felamimailAccount[0]['id']; $globalName = $filter->getValue(); $parent = true; break; case 'globalname': $globalName = $filter->getValue(); if ($filter->getOperator() == 'startswith') { $parent = true; $globalName = substr($globalName, 0, -1); } break; } } $resultArray = array(); $accountId = (array) $accountId; foreach ($accountId as $id) { $account = Felamimail_Controller_Account::getInstance()->get($id); if ($parent === true) { $folders = $this->_getFoldersFromIMAP($account, $globalName); foreach ($folders as $folder) { $resultArray[] = $this->get(self::encodeFolderUid($folder['globalName'], $id)); } } else { $resultArray[] = $this->get(self::encodeFolderUid(Felamimail_Model_Folder::encodeFolderName($globalName), $id)); } } $result = new Tinebase_Record_RecordSet('Felamimail_Model_Folder', $resultArray, true); return $result; }
/** * Search for records matching given filter * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param Tinebase_Model_Pagination $_pagination * @param array|string|boolean $_cols columns to get, * per default / use self::IDCOL or TRUE to get only ids * @return Tinebase_Record_RecordSet|array * * @todo implement optimizations on flags and security sorting * @todo implement messageuid,account_id search */ public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Model_Pagination $_pagination = NULL, $_cols = '*') { /* Tinebase_Core::getLogger()->alert(__METHOD__ . '#####::#####' . __LINE__ . ' Message Search = $_filter ' . print_r($_filter,true)); Tinebase_Core::getLogger()->alert(__METHOD__ . '#####::#####' . __LINE__ . ' Message Search = $_pagination' . print_r($_filter,true)); Tinebase_Core::getLogger()->alert(__METHOD__ . '#####::#####' . __LINE__ . ' Message Search = $_cols' . print_r($_cols,true)); */ $return = null; $messages = array(); $filterObjects = $_filter->getFilterObjects(); $imapFilters = $this->_parseFilterGroup($_filter, $_pagination); $pagination = !$_pagination ? new Tinebase_Model_Pagination(NULL, TRUE) : $_pagination; if (empty($imapFilters['paths'])) { $paths = $this->_getAllFolders(); $imapFilters['paths'] = $this->_getFoldersInfo($paths); } // TODO: do pagination on $ids and return after getMultiple if ($imapFilters['filters'] == 'Id') { $ids = $filterObjects[0]->getValue(); $ids = $this->_doPagination((array) $ids, $pagination); if ($_cols === TRUE) { return empty($ids) ? array() : $ids; } else { return empty($ids) ? $this->_rawDataToRecordSet(array()) : $this->getMultiple($ids); } } else { $ids = $this->_getIds($imapFilters, $_pagination); // get Summarys and merge results foreach ($ids as $folderId => $idsInFolder) { $folder = Felamimail_Controller_Folder::getInstance()->get($folderId); $imap = Felamimail_Backend_ImapFactory::factory($folder->account_id); $imap->selectFolder(Felamimail_Model_Folder::encodeFolderName($folder->globalname)); $idsInFolder = count($ids) === 1 ? $this->_doPagination($idsInFolder, $_pagination) : $idsInFolder; // do pagination early $messagesInFolder = $imap->getSummary($idsInFolder, null, null, $folderId); if (count($ids) === 1) { $tmp = array(); // We cannot trust the order we get from getSummary(), so we'll have to // put it the right order, defined by $idsInFolder // TODO: Put it into Felamilail_Backend_Imap->getSummary()???? foreach ($idsInFolder as $id) { $tmp[$id] = $messagesInFolder[$id]; } $messagesInFolder = $tmp; unset($tmp); } $messages = array_merge($messages, $messagesInFolder); if (count($ids) !== 1 && count($messages) > 1000) { throw new Felamimail_Exception_IMAPCacheTooMuchResults(); } } if (count($ids) === 1 && !in_array($pagination->sort, $this->_imapSortParams) || count($ids) > 1) { $callback = new Felamimail_Backend_Cache_Imap_MessageComparator($pagination); uasort($messages, array($callback, 'compare')); } } if (empty($messages)) { return $this->_rawDataToRecordSet(array()); } // Apply Pagination and get the resulting summary $page = count($ids) === 1 ? $messages : $this->_doPagination($messages, $_pagination); // $limit = empty($pagination->limit) ? count($messages) : $pagination->limit; // $chunked = array_chunk($messages, $limit, true); // $chunkIndex = empty($pagination->start) ? 0 : $pagination->start/$limit; // Put headers into model // if($imapFilters['filters'] == 'Id'){ // $return = empty($chunked[$chunkIndex])?new Tinebase_Record_RecordSet('Felamimail_Model_Message', array(), true): new Tinebase_Record_RecordSet('Felamimail_Model_Message', $chunked[$chunkIndex], true); // }else $return = empty($page) ? $this->_rawDataToRecordSet(array()) : $this->_rawDataToRecordSet($this->_createModelMessageArray($page)); Tinebase_Core::getLogger()->alert(__METHOD__ . '#####::#####' . __LINE__ . ' Imap Sort = $sorted ' . print_r($messages, true)); return $return; // // Tinebase_Core::getLogger()->alert(__METHOD__ . '#####::#####' . __LINE__ . ' Could\'nt use Imap directly' . print_r($return,true)); // $aux = new Felamimail_Backend_Cache_Sql_Message(); // $return = $aux->search($_filter,$_pagination, $_cols); //Tinebase_Core::getLogger()->alert(__METHOD__ . '#####::#####' . __LINE__ . ' Message Search = $retorno' . print_r($retorno,true)); }
/** * the client cannot handle {condition: ...., filters: ....} syntax * * @param array $result * @param Tinebase_Model_Filter_FilterGroup $_filtergroup * @param bool $_valueToJson resolve value for json api? * * @todo move this to filtergroup? */ protected function _filterGroupToArrayWithoutCondition(&$result, Tinebase_Model_Filter_FilterGroup $_filtergroup, $_valueToJson) { $filterObjects = $_filtergroup->getFilterObjects(); foreach ($filterObjects as $filter) { if ($filter instanceof Tinebase_Model_Filter_FilterGroup) { $this->_filterGroupToArrayWithoutCondition($result, $filter, $_valueToJson); } else { $result[] = $filter->toArray($_valueToJson); } } }
/** * appends filter to request * * @param Tinebase_Model_Filter_FilterGroup $_filter * @return void */ protected function _appendFilter($_filter, $_condition = ' AND ') { if ($_filter) { $parms = array(); foreach ($_filter->getFilterObjects() as $filterObject) { switch ($filterObject->getOperator()) { case 'equals': $op = '='; break; case 'contains': $op = 'LIKE'; break; case 'not': $op = '!='; break; case 'greater': $op = '>'; break; case 'less': $op = '<'; break; } $field = $filterObject->getField(); $value = $filterObject->getValue(); switch ($field) { case 'query': $parms[] = "(id = '{$value}' OR subject LIKE '{$value}')"; break; case 'status': if ($op !== '=') { $idx = array_search($value, RequestTracker_Model_Ticket::$status); if ($op == '>') { $status = array_slice(RequestTracker_Model_Ticket::$status, 0, $idx + 1); } else { $status = array_slice(RequestTracker_Model_Ticket::$status, $idx, count(RequestTracker_Model_Ticket::$status)); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__FILE__ . '::' . __LINE__ . ' filter for status :' . print_r($status, true)); } $parms[] = "(status = '" . implode("' OR status = '", $status) . "')"; break; } // fall through for '=' // fall through for '=' default: $parms[] = "{$field} {$op} '{$value}'"; break; } } $this->_httpClient->setParameterGet('query', implode($_condition, $parms)); } }
/** * Search for records matching given filter * * @param Tinebase_Model_Filter_FilterGroup $_filter * @param Tinebase_Model_Pagination $_pagination * @param array|string|boolean $_cols columns to get, * per default / use self::IDCOL or TRUE to get only ids * @return Tinebase_Record_RecordSet|array * * @todo implement optimizations on flags and security sorting * @todo implement messageuid,account_id search */ public function search(Tinebase_Model_Filter_FilterGroup $_filter = NULL, Tinebase_Model_Pagination $_pagination = NULL, $_cols = '*') { $return = null; $resultIds = array(); $messages = array(); $filterObjects = $_filter->getFilterObjects(); $imapFilters = $this->_parseFilterGroup($_filter, $_pagination); $pagination = !$_pagination ? new Tinebase_Model_Pagination(NULL, TRUE) : $_pagination; $searchTotalCount = 0; if ($imapFilters['filters'] == 'Id') { $ids = $filterObjects[0]->getValue(); $ids = $this->_doPagination($ids, $pagination); if ($_cols === TRUE) { return empty($ids) ? array() : $ids; } else { return empty($ids) ? $this->_rawDataToRecordSet(array()) : $this->getMultiple($ids); } } else { $settings = Expressomail_Controller::getInstance()->getConfigSettings(TRUE); $maxresults = $settings[Expressomail_Config::IMAPSEARCHMAXRESULTS]; if (empty($imapFilters['paths'])) { $imapFilters['paths'] = $this->_getAllFolders(); } // get Summarys and merge results foreach (array_keys($imapFilters['paths']) as $folderId) { if (isset($imapFilters['paths'][$folderId]['isSelectable']) && $imapFilters['paths'][$folderId]['isSelectable'] === false) { continue; } $folder = Expressomail_Backend_Folder::decodeFolderUid($folderId); $accountId = $folder['accountId']; $globalname = $folder['globalName']; $imap = Expressomail_Backend_ImapFactory::factory($accountId); $imap->selectFolder($globalname); $sort = $this->_getImapSortParams($_pagination); $idsInFolder = $imap->sort((array) $sort, (array) $imapFilters['filters']); if ($_cols === true) { foreach ($idsInFolder as $idInFolder) { $resultIds[] = self::createMessageId($folder['accountId'], $folderId, $idInFolder); } unset($idsInFolder); unset($idInFolder); } else { $searchTotalCount += count($idsInFolder); if (count($imapFilters['paths']) !== 1 && $searchTotalCount > $maxresults) { throw new Expressomail_Exception_IMAPCacheTooMuchResults(); } if (count($imapFilters['paths']) === 1 && count($_cols) == 2 && $_cols[0] == '_id_' && $_cols[1] == 'messageuid') { $return = array(); $aux = Expressomail_Backend_Folder::decodeFolderUid($folderId); foreach ($idsInFolder as $value) { $messageId = self::createMessageId($aux['accountId'], $folderId, $value); $return[$messageId] = $value; } return $return; } $idsInFolder = count($imapFilters['paths']) === 1 ? $this->_doPagination($idsInFolder, $_pagination) : $idsInFolder; // do pagination early $messagesInFolder = $this->_getSummary($imap, $idsInFolder, $folderId); //$messagesInFolder = $imap->getSummary($idsInFolder, null, null, $folderId); if (count($imapFilters['paths']) === 1) { $tmp = array(); // We cannot trust the order we get from getSummary(), so we'll have to // put it the right order, defined by $idsInFolder // TODO: Put it into Felamilail_Backend_Imap->getSummary()???? foreach ($idsInFolder as $id) { $tmp[$id] = $messagesInFolder[$id]; } $messagesInFolder = $tmp; unset($tmp); } unset($idsInFolder); $messages = array_merge($messages, $messagesInFolder); unset($messagesInFolder); } } if ($_cols === true) { return $resultIds; } if (count($imapFilters['paths']) === 1 && !in_array($pagination->sort, $this->_imapSortParams) || count($imapFilters['paths']) > 1) { $callback = new Expressomail_Backend_MessageComparator($pagination); uasort($messages, array($callback, 'compare')); } } if (empty($messages)) { return $this->_rawDataToRecordSet(array()); } // Apply Pagination and get the resulting summary $messages = count($imapFilters['paths']) === 1 ? $messages : $this->_doPagination($messages, $_pagination); $return = empty($messages) ? $this->_rawDataToRecordSet(array()) : $this->_rawDataToRecordSet($this->_createModelMessageArray($messages), $searchTotalCount); return $return; }