I had to modify class.mailfetch.php; it seems to be working fine on the test server with these changes. I'll move it to production.
function processEmails() {
//SergioMAil
global $ost;
//SergioMAil
// We need a connection
if (!$this->mbox)
return false;
// Get basic fetch settings
$archiveFolder = $this->getArchiveFolder();
$deleteFetched = $this->canDeleteEmails();
$max = $this->getMaxFetch() ?: 30; // default to 30 if not set
// Get message count in the Fetch Folder
if (!($messageCount = $this->mbox->countMessages()))
return 0;
// If the number of emails in the folder are more than Max Fetch
// then process the latest $max emails - this is necessary when
// fetched emails are not getting archived or deleted, which might
// lead to fetcher being stuck 4ever processing old emails already
// fetched
if ($messageCount > $max) {
// Latest $max messages
//SergioMAil
// 1) Corregir off-by-one y preparar orden descendente seguro
$start = $messageCount - $max + 1; // <- +1
$messages = range($start, $messageCount);
//$messages = range($messageCount-$max, $messageCount);
//SergioMAil
} else {
// Create a range of message sequence numbers (msgno) to fetch
// starting from the oldest taking max fetch into account
$messages = range(1, min($max, $messageCount));
}
//SergioMAil
// 2) Iterar en DESC para que mover no cambie los índices aún no procesados
$messages = array_reverse($messages);
//SergioMAil
$defaults = [
'emailId' => $this->getEmailId()
];
$msgs = $errors = 0;
//SergioMAil
if($ost){
$subj = "processEmailsSergio";
$msg = json_encode([
"messageCount" => $messageCount,
"max" => $max,
"archiveFolder" => $archiveFolder,
"deleteFetched" => $deleteFetched
]);
$ost->logDebug($subj, $msg, true);
}
//SergioMAil
// TODO: Use message UIDs instead of ids
foreach ($messages as $i) {
//SergioMAil
$result = false; // <- evitar uso sin inicializar
//SergioMAil
try {
// Okay, let's try to create a ticket
if (($result=$this->processMessage($i, $defaults))) {
// Mark the message as "Seen" (IMAP only)
$this->mbox->markAsSeen($i);
// Attempt to move the message if archive folder is set or
if ($archiveFolder)
$this->mbox->moveMessage($i, $archiveFolder);
elseif ($deleteFetched) // else delete if deletion is desired
$this->mbox->removeMessage($i);
$msgs++;
$errors = 0; // We are only interested in consecutive errors.
} else {
$errors++;
}
} catch (\Throwable $t) {
// If we have result then exception happened after email
// processing and shouldn't count as an error
if (!$result)
$errors++;
// log the exception as a debug message
$this->logDebug($t->getMessage());
}
}
// Expunge the mailbox
$this->mbox->expunge();
// Warn on excessive errors - when errors are more than email
// processed successfully.
if ($errors > $msgs) {
$warn = sprintf("%s\n\n%s [%d/%d - %d/%d]",
// Mailbox Info
sprintf(_S('Excessive errors processing emails for %1$s (%2$s).'),
$this->mbox->getHostInfo(), $this->getEmail()),
// Fetch Folder
sprintf('%s (%s)',
_S('Please manually check the Fetch Folder'),
$this->getFetchFolder()),
// Counts - sort of cryptic but useful once we document
// what it means
$messageCount, $max, $msgs, $errors);
$this->logWarning($warn);
}
return $msgs;
}