J'essaie de développer un webmail via PHP/Symfony en utilisant le protocole IMAP.
L'idée est de récupérer les mails en vérifiant qu'ils contiennent des pièces jointes. Stocker les emails dans le cache et lors de la prochaine connexion interroger le serveur mail que s'il y a de nouveaux mails. Une fois cette dernière opération faite, afficher les nouveaux mails (récupérer sur le serveur) et les anciens mails stocker dans le cache.
J'ai imaginé ce système pour économiser du temps de chargement, mais la page ne s'affiche qu'au bout de 5 seconde, ce qui peut être excessif !
Voici mon code :
/**
* @Route("/emails/{emailBox}/{nb?}", name="list_emails")
*/
public function listEmails(Request $request, string $emailBox, PaginatorInterface $paginator, $nb): Response
{
$login = $this->getUser()->getWorkemail();
$mbox = $this->logImap($emailBox);
// Check if $nb is set, otherwise, set the default value
$batchSize = $nb !== null ? $nb : 20;
if ($mbox === false) {
$session->getFlashBag()->add('danger', 'La connexion a échoué. Vérifiez vos paramètres!');
} else {
$currentPage = $request->query->getInt('page', 1);
$cache = new FilesystemAdapter();
// Fetch all emails from IMAP server
$emails = [];
$allEmailNumbers = imap_search($mbox, 'ALL');
if ($allEmailNumbers) {
foreach ($allEmailNumbers as $emailNumber) {
$overview = imap_fetch_overview($mbox, $emailNumber);
if ($overview) {
$emailData = [
'emailNumber' => $overview[0]->msgno,
'seen' => $overview[0]->seen,
'date' => $overview[0]->date,
'subject' => $overview[0]->subject,
'uid' => $overview[0]->uid,
'from' => $overview[0]->from,
'to' => $overview[0]->to,
'hasAttachment' => false,
];
$structure = imap_fetchstructure($mbox, $emailNumber);
if ($structure && isset($structure->parts)) {
foreach ($structure->parts as $part) {
if (isset($part->disposition) && strtoupper($part->disposition) === 'ATTACHMENT') {
$emailData['hasAttachment'] = true;
break;
}
}
}
$emails[] = $emailData;
}
}
}
// Sort emails by the 'date' field in descending order (most recent first)
usort($emails, function ($a, $b) {
return strtotime($b['date']) - strtotime($a['date']);
});
// Store all emails in the cache
$cacheKey = 'emails_' . $emailBox;
$cacheItem = $cache->getItem($cacheKey);
$cacheItem->set($emails);
$cache->save($cacheItem);
// Paginate all emails
$pagination = $paginator->paginate(
$emails,
intval($currentPage),
intval($batchSize),
['totalItems' => count($emails)]
);
imap_close($mbox);
}
switch ($emailBox) {
case 'INSENT':
$route = 'core/emails/insent.html.twig';
break;
case 'INTRASH':
$route = 'core/emails/intrash.html.twig';
break;
case 'INBOX':
default:
$route = 'core/emails/inbox.html.twig';
break;
}
return $this->render($route, [
'mgs' => $pagination ?? [],
'login' => $login,
'nb' => $batchSize,
]);
}