Installation
Run composer require dadadev/imap-bundle in your Symfony project. If using Symfony Flex, the bundle auto-registers. For older versions (2.8–3.x), manually add new DaDaDev\ImapBundle\ImapBundle() to AppKernel.
Basic Configuration
Configure config/packages/imap.yaml (Symfony 4+) or app/config/config.yml (Symfony 2.8–3.x):
imap:
connections:
default:
mailbox: "{your.imap.server:993/imap/ssl/novalidate-cert}INBOX"
username: "[email protected]"
password: "yourpassword"
First Use Case: Fetch Emails
Inject the DaDaDev\ImapBundle\Service\ImapService into a controller/service:
use DaDaDev\ImapBundle\Service\ImapService;
public function __construct(private ImapService $imapService) {}
public function fetchEmails(): array
{
return $this->imapService->getConnection('default')->getMessages();
}
Connection Management
imap.yaml (e.g., production, staging).getConnection('connection_name').Fetching and Processing Emails
getMessages() to retrieve raw email data (array of php-imap message objects).
$messages = $this->imapService->getConnection('default')->getMessages();
getMessages(['unseen' => true]) or getMessages(['since' => '15-Jul-2023']).attachments_dir in YAML to auto-save attachments to a directory. Access via:
$message->getAttachments(); // Returns array of paths
Email Parsing
php-imap's built-in methods (e.g., $message->getHeader(), $message->getBody()) or extend the bundle:
$headers = $message->getHeader();
$body = $message->getBody();
Marking as Read/Deleted
php-imap methods via the bundle:
$this->imapService->getConnection('default')->markAsRead($messageId);
$this->imapService->getConnection('default')->deleteMessage($messageId);
Event-Driven Processing
kernel.request) to periodically check for new emails:
$this->imapService->getConnection('default')->checkForNewMessages();
$this->messageBus->dispatch(new ProcessEmailMessage($message));
$emailEntity = (new Email())
->setSubject($message->getHeader('subject'))
->setBody($message->getBody());
$entityManager->persist($emailEntity);
#[Route('/emails', methods: ['GET'])]
public function listEmails(): JsonResponse
{
return $this->json($this->imapService->getConnection('default')->getMessages());
}
Connection Timeouts
setTimeout() in the connection config (if supported by the underlying php-imap):
imap:
connections:
default:
mailbox: "..."
timeout: 30 # seconds
SSL/TLS Validation
novalidate-cert flag disables SSL cert validation (insecure). For production:
novalidate-cert in config.Attachment Paths
attachments_dir isn’t writable, attachments won’t save. Verify permissions:
chmod -R 755 var/imap/attachments
%kernel.project_dir%/var/imap/attachments for portability.Character Encoding
server_encoding (e.g., UTF-8) may corrupt email content. Test with:
$this->imapService->getConnection('default')->setEncoding('UTF-8');
Memory Limits
getMessages(['limit' => 50]) to paginate.Thread Safety
Enable IMAP Debugging Add to your connection config:
imap:
connections:
default:
debug: true
Logs will appear in var/log/dev.log.
Check IMAP Server Logs
Server-side logs (e.g., dovecot.log) may reveal connection issues.
Validate Credentials
Test credentials manually with telnet or openssl:
openssl s_client -connect imap.example.com:993 -crlf
a login username password
Custom Message Processing
Extend the DaDaDev\ImapBundle\Message\Message class to add domain-specific methods:
class CustomMessage extends Message
{
public function isSpam(): bool
{
return str_contains($this->getHeader('subject'), 'SPAM');
}
}
Override the bundle’s service definition to use your class.
Add Connection Options
Extend the DaDaDev\ImapBundle\Service\ImapConnection class to support custom php-imap options:
$connection->setOption(IN_IMAP_KEEPALIVE, 1);
Event Listeners Dispatch events for critical actions (e.g., new email received):
// In your service:
$this->eventDispatcher->dispatch(new EmailReceivedEvent($message));
Listen globally in Symfony:
services:
App\EventListener\EmailListener:
tags:
- { name: kernel.event_listener, event: email.received, method: onEmailReceived }
Mocking for Tests
Use php-imap's mocking capabilities or create a test double for ImapService:
$mockConnection = $this->createMock(ImapConnection::class);
$mockConnection->method('getMessages')->willReturn([$mockMessage]);
$this->imapService->setConnection('default', $mockConnection);
Rate Limiting
Implement a decorator around ImapService to enforce rate limits:
class RateLimitedImapService implements ImapServiceInterface
{
public function getMessages(array $criteria = []): array
{
if ($this->isRateLimited()) {
throw new \RuntimeException('Rate limit exceeded');
}
return $this->decorated->getMessages($criteria);
}
}
How can I help you explore Laravel packages today?