Partage
  • Partager sur Facebook
  • Partager sur Twitter

IMAP PHP : vitesse lecture des mails

    12 avril 2024 à 10:06:02

    Bonjour,

    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,
        ]);
    }

    En vous remerciant de votre aide

    • Partager sur Facebook
    • Partager sur Twitter
      15 avril 2024 à 14:17:42

      Voici ce que me propose une IA : 

      $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!');
          return $this->renderErrorPage();
      }
      
      $currentPage = $request->query->getInt('page', 1);
      
      $cache = new FilesystemAdapter();
      
      // Check if emails are already cached
      $cacheKey = 'emails_' . $emailBox;
      $cachedEmails = $cache->getItem($cacheKey)->get() ?: [];
      $highestUid = $cache->getItem('highest_uid')->get() ?: 0;
      
      // Fetch all emails from IMAP server
      $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;
                          }
                      }
                  }
      
                  // Check if the email with the same UID already exists in cache
                  $existingEmailIndex = array_search($emailData['uid'], array_column($cachedEmails, 'uid'));
                  if ($existingEmailIndex !== false) {
                      // Update seen status of the email if it exists in cache
                      $cachedEmails[$existingEmailIndex]['seen'] = $emailData['seen'];
                  } else {
                      // Add the email to cache if it doesn't exist
                      $cachedEmails[] = $emailData;
                  }
              }
          }
      
          // Update the highest UID
          $newHighestUid = max(array_column($cachedEmails, 'uid'));
          $cacheItem = $cache->getItem('highest_uid');
          $cacheItem->set($newHighestUid);
          $cache->save($cacheItem);
      }
      
      // Sort emails by the 'date' field in descending order (most recent first)
      usort($cachedEmails, function ($a, $b) {
          return strtotime($b['date']) - strtotime($a['date']);
      });
      
      // Store all emails in the cache
      $cacheItem = $cache->getItem($cacheKey);
      $cacheItem->set(array_values($cachedEmails)); // Reset array keys
      $cache->save($cacheItem);
      
      // Paginate all emails
      $pagination = $paginator->paginate(
          $cachedEmails,
          $currentPage,
          $batchSize,
          ['totalItems' => count($cachedEmails)]
      );
      
      // Close the connection
      imap_close($mbox);
      
      // Render the appropriate page
      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,
      ]);
      

      Cela semble fonctionner ! 

      • Partager sur Facebook
      • Partager sur Twitter

      IMAP PHP : vitesse lecture des mails

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      • Editeur
      • Markdown