/**
  * create folder
  *
  * @param string|Felamimail_Model_Account $_accountId
  * @param string $_folderName to create
  * @param string $_parentFolder
  * @return Felamimail_Model_Folder
  * @throws Felamimail_Exception_IMAPServiceUnavailable
  */
 public function create($_accountId, $_folderName, $_parentFolder = '')
 {
     $account = $_accountId instanceof Felamimail_Controller_Account ? $_accountId : Felamimail_Controller_Account::getInstance()->get($_accountId);
     $this->_delimiter = $account->delimiter;
     $foldername = $this->_prepareFolderName($_folderName);
     $globalname = empty($_parentFolder) ? $foldername : $_parentFolder . $this->_delimiter . $foldername;
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Trying to create new folder: ' . $globalname . ' (parent: ' . $_parentFolder . ')');
     }
     $imap = Felamimail_Backend_ImapFactory::factory($account);
     try {
         $imap->createFolder(Felamimail_Model_Folder::encodeFolderName($foldername), empty($_parentFolder) ? NULL : Felamimail_Model_Folder::encodeFolderName($_parentFolder), $this->_delimiter);
         // create new folder
         $folder = new Felamimail_Model_Folder(array('localname' => $foldername, 'globalname' => $globalname, 'account_id' => $account->getId(), 'parent' => $_parentFolder));
         $folder = $this->_backend->create($folder);
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Create new folder: ' . $globalname);
         }
     } catch (Zend_Mail_Storage_Exception $zmse) {
         // perhaps the folder already exists
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Could not create new folder: ' . $globalname . ' (' . $zmse->getMessage() . ')');
         }
         // reload folder cache of parent
         $parentSubs = $this->_cacheController->update($account, $_parentFolder);
         $folder = $parentSubs->filter('globalname', $globalname)->getFirstRecord();
         if ($folder === NULL) {
             throw new Felamimail_Exception_IMAPServiceUnavailable($zmse->getMessage());
         }
     }
     // update parent (has_children)
     $this->_updateHasChildren($_accountId, $_parentFolder, 1);
     return $folder;
 }
 /**
  * the singleton pattern
  *
  * @return Felamimail_Controller_Cache_Folder
  */
 public static function getInstance()
 {
     if (self::$_instance === NULL) {
         self::$_instance = new Felamimail_Controller_Cache_Folder();
     }
     return self::$_instance;
 }
Пример #3
0
 /**
  * the singleton pattern
  *
  * @return Felamimail_Controller_Cache_Folder
  */
 public static function getInstance()
 {
     if (self::$_instance === NULL) {
         $adapter = Tinebase_Core::getConfig()->messagecache;
         $adapter = empty($adapter) ? 'sql' : $adapter;
         $classname = 'Felamimail_Controller_Cache_' . ucfirst($adapter) . '_Folder';
         self::$_instance = $classname::getInstance();
     }
     return self::$_instance;
 }
Пример #4
0
 /**
  * Sets up the fixture.
  * This method is called before a test is executed.
  *
  * @access protected
  */
 protected function setUp()
 {
     // get (or create) test accout
     $this->_account = Felamimail_Controller_Account::getInstance()->search()->getFirstRecord();
     // init controller and imap backend
     $this->_controller = Felamimail_Controller_Cache_Message::getInstance();
     $this->_imap = Felamimail_Backend_ImapFactory::factory($this->_account);
     try {
         $this->_imap->createFolder($this->_testFolderName, '', $this->_account->delimiter);
     } catch (Zend_Mail_Storage_Exception $zmse) {
         // exists
     }
     $this->_imap->selectFolder($this->_testFolderName);
     // init folder cache and get INBOX
     Felamimail_Controller_Cache_Folder::getInstance()->update($this->_account->getId());
     $this->_folder = $this->_getFolder($this->_testFolderName);
     $this->_emailTestClass = new Felamimail_Controller_MessageTest();
     $this->_emailTestClass->setup();
 }
Пример #5
0
 /**
  * test search with cache
  * - test text_plain.eml message
  * - test from header
  */
 public function testSearchWithCache()
 {
     // get inbox folder id
     Felamimail_Controller_Cache_Folder::getInstance()->update($this->_account->getId());
     $folderBackend = new Felamimail_Backend_Folder();
     $folder = Felamimail_Controller_Folder::getInstance()->getByBackendAndGlobalName($this->_account->getId(), $this->_testFolderName);
     // clear cache and empty folder
     $this->_cache->clear($folder->getId());
     Felamimail_Controller_Folder::getInstance()->emptyFolder($folder->getId());
     // append message
     $this->_appendMessage('text_plain.eml', $this->_folder);
     // search messages in test folder
     $this->_cache->updateCache($folder);
     $result = $this->_controller->search($this->_getFilter($folder->getId()));
     //print_r($result->toArray());
     // check result
     $firstMessage = $result->getFirstRecord();
     $this->_createdMessages->addRecord($firstMessage);
     $this->assertGreaterThan(0, count($result));
     $this->assertEquals($folder->getId(), $firstMessage->folder_id);
     $this->assertEquals("Re: [gentoo-dev] `paludis --info' is not like `emerge --info'", $firstMessage->subject);
     $this->assertEquals('Pipping, Sebastian (Luxembourg)', $firstMessage->from_name);
     $this->assertEquals('*****@*****.**', $firstMessage->from_email);
     $this->assertEquals(array('*****@*****.**', '*****@*****.**'), $firstMessage->to);
     // check cache entries
     $cacheBackend = new Felamimail_Backend_Cache_Sql_Message();
     $cachedMessage = $cacheBackend->get($firstMessage->getId());
     $this->assertEquals($folder->getId(), $cachedMessage->folder_id);
     $this->assertEquals(Tinebase_DateTime::now()->format('Y-m-d'), $cachedMessage->timestamp->format('Y-m-d'));
     // clear cache
     $this->_cache->clear($folder->getId());
 }
 /**
  * get mailbox
  *
  * @param string $name
  * @param boolean $createFolder
  * @return Felamimail_Model_Folder|NULL
  */
 protected function _getFolder($name, $createFolder = TRUE)
 {
     Felamimail_Controller_Cache_Folder::getInstance()->update($this->_account->getId());
     try {
         $folder = Felamimail_Controller_Folder::getInstance()->getByBackendAndGlobalName($this->_account->getId(), $name);
     } catch (Tinebase_Exception_NotFound $tenf) {
         $folder = $createFolder ? Felamimail_Controller_Folder::getInstance()->create($this->_account, $name) : NULL;
     }
     return $folder;
 }
 /**
  * update folder cache
  *
  * @param string $accountId
  * @param string  $folderName of parent folder
  * @return array of (sub)folders in cache
  */
 public function updateFolderCache($accountId, $folderName)
 {
     // this may take longer
     $this->_longRunningRequest(300);
     $result = Felamimail_Controller_Cache_Folder::getInstance()->update($accountId, $folderName, TRUE);
     return $this->_multipleRecordsToJson($result);
 }
Пример #8
0
 /**
  * get system folder for account
  * 
  * @param string|Felamimail_Model_Account $_account
  * @param string $_systemFolder
  * @return NULL|Felamimail_Model_Folder
  */
 public function getSystemFolder($_account, $_systemFolder)
 {
     $account = $_account instanceof Felamimail_Model_Account ? $_account : $this->get($_account);
     $changed = $this->_addFolderDefaults($account);
     if ($changed) {
         // need to use backend update because we prohibit the change of some fields in _inspectBeforeUpdate()
         $account = $this->_backend->update($account);
     }
     $systemFolderField = $this->_getSystemFolderField($_systemFolder);
     $folderName = $account->{$systemFolderField};
     if (empty($folderName)) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' No ' . $_systemFolder . ' folder set in account.');
         }
         return NULL;
     }
     // check if folder exists on imap server
     $imapBackend = $this->_getIMAPBackend($account);
     if ($imapBackend && $imapBackend->getFolderStatus(Felamimail_Model_Folder::encodeFolderName($folderName)) === false) {
         $systemFolder = $this->_createSystemFolder($account, $folderName);
         if ($systemFolder->globalname !== $folderName) {
             $account->{$systemFolderField} = $systemFolder->globalname;
             $this->_backend->update($account);
         }
     } else {
         try {
             $systemFolder = Felamimail_Controller_Folder::getInstance()->getByBackendAndGlobalName($account->getId(), $folderName);
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Found system folder: ' . $folderName);
             }
         } catch (Tinebase_Exception_NotFound $tenf) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $tenf->getMessage());
             }
             $splitFolderName = Felamimail_Model_Folder::extractLocalnameAndParent($_systemFolder, $_account->delimiter);
             Felamimail_Controller_Cache_Folder::getInstance()->update($account, $splitFolderName['parent'], TRUE);
             $systemFolder = Felamimail_Controller_Folder::getInstance()->getByBackendAndGlobalName($account->getId(), $folderName);
         }
     }
     return $systemFolder;
 }
 /**
  * update/synchronize flags
  * 
  * @param string|Felamimail_Model_Folder $_folder
  * @param integer $_time
  * @return Felamimail_Model_Folder
  * 
  * @todo only get flags of current batch of messages from imap?
  * @todo add status/progress to start at later messages when this is called next time?
  */
 public function updateFlags($_folder, $_time = 60)
 {
     // always read folder from database
     $folder = Felamimail_Controller_Folder::getInstance()->get($_folder);
     if ($folder->cache_status !== Felamimail_Model_Folder::CACHE_STATUS_COMPLETE) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Do not update flags of incomplete folder ' . $folder->globalname);
         }
         return $folder;
     }
     if ($this->_availableUpdateTime == 0) {
         $this->_availableUpdateTime = $_time;
         $this->_timeStart = microtime(true);
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updating flags of folder ' . $folder->globalname . ' / start time: ' . Tinebase_DateTime::now()->toString() . ' / available seconds: ' . ($this->_availableUpdateTime - $this->_timeElapsed));
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Folder: ' . print_r($folder->toArray(), true));
     }
     $imap = Felamimail_Backend_ImapFactory::factory($folder->account_id);
     // switch to folder (read-only)
     $imap->examineFolder(Felamimail_Model_Folder::encodeFolderName($folder->globalname));
     if ($folder->supports_condstore) {
         $this->_updateCondstoreFlags($imap, $folder);
     } else {
         $this->_updateAllFlags($imap, $folder);
     }
     $updatedCounters = Felamimail_Controller_Cache_Folder::getInstance()->getCacheFolderCounter($folder);
     $folder = Felamimail_Controller_Folder::getInstance()->updateFolderCounter($folder, array('cache_unreadcount' => $updatedCounters['cache_unreadcount']));
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' New unreadcount after flags update: ' . $updatedCounters['cache_unreadcount']);
     }
     return $folder;
 }
 /**
  * update the folder cache
  * 
  * @throws Syncroton_Exception_Status_FolderSync
  */
 protected function _updateFolderCache()
 {
     $account = $this->_getAccount();
     if (!$account) {
         return;
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " accountData " . print_r($account->toArray(), true));
     }
     try {
         Felamimail_Controller_Cache_Folder::getInstance()->update($account);
     } catch (Felamimail_Exception_IMAPServiceUnavailable $feisu) {
         if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) {
             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " Could not update folder cache: " . $feisu);
         }
         throw new Syncroton_Exception_Status_FolderSync(Syncroton_Exception_Status_FolderSync::FOLDER_SERVER_ERROR);
     } catch (Felamimail_Exception_IMAPInvalidCredentials $feiic) {
         Tinebase_Exception::log($feiic, null, array('accountname' => $account->name));
     }
 }
 /**
  * update folder counts and returns list of affected folders
  * 
  * @param array $_folderCounter (folderId => unreadcounter)
  * @return Tinebase_Record_RecordSet of affected folders
  * @throws Felamimail_Exception
  */
 protected function _updateFolderCounts($_folderCounter)
 {
     foreach ($_folderCounter as $folderId => $counter) {
         $folder = Felamimail_Controller_Folder::getInstance()->get($folderId);
         // get error condition and update array by checking $counter keys
         if (isset($counter['incrementUnreadCounter']) || array_key_exists('incrementUnreadCounter', $counter)) {
             // this is only used in clearFlags() atm
             $errorCondition = $folder->cache_unreadcount + $counter['incrementUnreadCounter'] > $folder->cache_totalcount;
             $updatedCounters = array('cache_unreadcount' => '+' . $counter['incrementUnreadCounter']);
         } else {
             if ((isset($counter['decrementMessagesCounter']) || array_key_exists('decrementMessagesCounter', $counter)) && (isset($counter['decrementUnreadCounter']) || array_key_exists('decrementUnreadCounter', $counter))) {
                 $errorCondition = $folder->cache_unreadcount < $counter['decrementUnreadCounter'] || $folder->cache_totalcount < $counter['decrementMessagesCounter'];
                 $updatedCounters = array('cache_totalcount' => '-' . $counter['decrementMessagesCounter'], 'cache_unreadcount' => '-' . $counter['decrementUnreadCounter']);
             } else {
                 throw new Felamimail_Exception('Wrong folder counter given: ' . print_r($_folderCounter, TRUE));
             }
         }
         if ($errorCondition) {
             // something went wrong => recalculate counter
             if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) {
                 Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' folder counters dont match => refresh counters');
             }
             $updatedCounters = Felamimail_Controller_Cache_Folder::getInstance()->getCacheFolderCounter($folder);
         }
         Felamimail_Controller_Folder::getInstance()->updateFolderCounter($folder, $updatedCounters);
     }
     return Felamimail_Controller_Folder::getInstance()->getMultiple(array_keys($_folderCounter));
 }
 /**
  * update folder cache
  *
  * @param string $accountId
  * @param string  $folderName of parent folder
  * @return array of (sub)folders in cache
  */
 public function updateFolderCache($accountId, $folderName)
 {
     $result = Felamimail_Controller_Cache_Folder::getInstance()->update($accountId, $folderName, TRUE);
     return $this->_multipleRecordsToJson($result);
 }
Пример #13
0
 /**
  * check and update mismatching folder counts (totalcount + unreadcount)
  * 
  * @param Felamimail_Model_Folder $_folder
  */
 protected function _checkAndUpdateFolderCounts(Felamimail_Model_Folder $_folder)
 {
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Checking foldercounts.');
     }
     $updatedCounters = Felamimail_Controller_Cache_Folder::getInstance()->getCacheFolderCounter($_folder);
     if ($this->_countMismatch($_folder, $updatedCounters)) {
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' something went wrong while in/decrementing counters => recalculate cache counters by counting rows in database.' . " Cache status cache total count: {$_folder->cache_totalcount} imap total count: {$_folder->imap_totalcount}");
         }
         Felamimail_Controller_Folder::getInstance()->updateFolderCounter($_folder, $updatedCounters);
     }
     if ($updatedCounters['cache_totalcount'] != $_folder->imap_totalcount) {
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' There are still messages missing in the cache: setting status to INCOMPLETE');
         }
         $_folder->cache_status == Felamimail_Model_Folder::CACHE_STATUS_INCOMPLETE;
     }
 }
Пример #14
0
 /**
  * return list of supported folders for this backend
  *
  * @return array
  */
 public function getAllFolders()
 {
     if (!Tinebase_Core::getUser()->hasRight('Felamimail', Tinebase_Acl_Rights::RUN)) {
         // no folders
         return array();
     }
     $defaultAccountId = Tinebase_Core::getPreference('Felamimail')->{Felamimail_Preference::DEFAULTACCOUNT};
     if (empty($defaultAccountId)) {
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " no default account set. Can't sync any folders.");
         }
         return array();
     }
     try {
         $account = Felamimail_Controller_Account::getInstance()->get($defaultAccountId);
     } catch (Tinebase_Exception_NotFound $ten) {
         // no folders
         return array();
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . " accountData " . print_r($account->toArray(), true));
     }
     // update folder cache
     Felamimail_Controller_Cache_Folder::getInstance()->updateCacheFolder($account);
     // get folders
     $folderController = Felamimail_Controller_Folder::getInstance();
     $folders = $folderController->getSubfolders($account->getId(), '');
     $result = array();
     foreach ($folders as $folder) {
         if (!empty($folder->parent)) {
             try {
                 $parent = $folderController->getByBackendAndGlobalName($folder->account_id, $folder->parent);
                 $parentId = $parent->getId();
             } catch (Tinebase_Exception_NotFound $ten) {
                 continue;
             }
         } else {
             $parentId = 0;
         }
         $result[$folder->getId()] = array('folderId' => $folder->getId(), 'parentId' => $parentId, 'displayName' => $folder->localname, 'type' => $this->_getFolderType($folder->localname));
     }
     #if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " folder result " . print_r($result, true));
     return $result;
 }
Пример #15
0
 /**
  * test update folder counter
  */
 public function testUpdateFolderCounter()
 {
     $inbox = $this->_getInbox();
     $this->_folderCountsTestHelper($inbox, array('cache_totalcount' => 0, 'cache_recentcount' => 0, 'cache_unreadcount' => 0), array('cache_totalcount' => 0, 'cache_unreadcount' => 0));
     $this->_folderCountsTestHelper($inbox, array('cache_totalcount' => "+200", 'cache_unreadcount' => "+25"), array('cache_totalcount' => 200, 'cache_unreadcount' => 25));
     $this->_folderCountsTestHelper($inbox, array('cache_totalcount' => "-1", 'cache_unreadcount' => "22"), array('cache_totalcount' => 199, 'cache_unreadcount' => 22));
     $this->_folderCountsTestHelper($inbox, array('cache_totalcount' => "-100", 'cache_unreadcount' => "-30"), array('cache_totalcount' => 99, 'cache_unreadcount' => 0));
     // reset
     $updatedCounters = Felamimail_Controller_Cache_Folder::getInstance()->getCacheFolderCounter($inbox);
     $this->assertEquals(0, $updatedCounters['cache_totalcount'], 'cache_totalcount does not match.');
     $this->assertEquals(0, $updatedCounters['cache_unreadcount'], 'cache_unreadcount does not match.');
 }
Пример #16
0
 /**
  * update/synchronize flags
  * 
  * @param string|Felamimail_Model_Folder $_folder
  * @param integer $_time
  * @return Felamimail_Model_Folder
  * 
  * @todo only get flags of current batch of messages from imap?
  * @todo add status/progress to start at later messages when this is called next time?
  */
 public function updateFlags($_folder, $_time = 60)
 {
     // always read folder from database
     $folder = Felamimail_Controller_Folder::getInstance()->get($_folder);
     if ($folder->cache_status !== Felamimail_Model_Folder::CACHE_STATUS_COMPLETE) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Do not update flags of incomplete folder ' . $folder->globalname);
         }
         return $folder;
     }
     if ($this->_availableUpdateTime == 0) {
         $this->_availableUpdateTime = $_time;
         $this->_timeStart = microtime(true);
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updating flags of folder ' . $folder->globalname . ' / start time: ' . Tinebase_DateTime::now()->toString() . ' / available seconds: ' . ($this->_availableUpdateTime - $this->_timeElapsed));
     }
     // get all flags for folder
     $imap = Felamimail_Backend_ImapFactory::factory($folder->account_id);
     $imap->selectFolder(Felamimail_Model_Folder::encodeFolderName($folder->globalname));
     $flags = $imap->getFlags(1, INF);
     for ($i = $folder->cache_totalcount; $i > 0; $i -= $this->_flagSyncCountPerStep) {
         $firstMessageSequence = $i - $this->_flagSyncCountPerStep >= 0 ? $i - $this->_flagSyncCountPerStep : 0;
         $messagesWithFlags = $this->_backend->getFlagsForFolder($folder->getId(), $firstMessageSequence, $this->_flagSyncCountPerStep);
         $this->_setFlagsOnCache($messagesWithFlags, $flags, $folder->getId());
         if (!$this->_timeLeft()) {
             break;
         }
     }
     $updatedCounters = Felamimail_Controller_Cache_Folder::getInstance()->getCacheFolderCounter($_folder);
     $folder = Felamimail_Controller_Folder::getInstance()->updateFolderCounter($folder, array('cache_unreadcount' => $updatedCounters['cache_unreadcount']));
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' New unreadcount after flags update: ' . $updatedCounters['cache_unreadcount']);
     }
     return $folder;
 }