Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Fetch Laravel Package

tedivm/fetch

Fetch is a PHP library for reading email and attachments via IMAP and POP. Connect to a mail server, authenticate, list messages, and access subjects, bodies, and attachments with a simple API (requires the PHP IMAP extension).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require tedivm/fetch
    

    Add to composer.json if using a custom namespace:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Fetch\\": "vendor/tedivm/fetch/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case: Connecting to IMAP

    use Fetch\IMAP\Client;
    use Fetch\IMAP\Connection;
    
    $connection = new Connection('imap.example.com', 993, true);
    $client = new Client($connection, 'username', 'password');
    $client->connect();
    
  3. Key Files to Explore

    • src/IMAP/Client.php – Core client logic.
    • src/IMAP/Connection.php – Connection handling.
    • src/IMAP/Message.php – Message parsing and manipulation.
    • src/IMAP/Exception/ – Error handling.

Implementation Patterns

Common Workflows

1. Fetching Emails

// Fetch all messages in the inbox
$messages = $client->getMessages('INBOX');

// Fetch a specific message
$message = $client->getMessage('INBOX', 1);

2. Searching Emails

// Search for unread emails
$unread = $client->search('INBOX', 'UNSEEN');

// Search with multiple criteria
$results = $client->search('INBOX', 'FROM "sender@example.com" SUBJECT "Hello"');

3. Handling Attachments

$message = $client->getMessage('INBOX', 1);
foreach ($message->getAttachments() as $attachment) {
    $attachment->saveTo('/path/to/save/' . $attachment->getName());
}

4. Streaming Large Emails

$message = $client->getMessage('INBOX', 1);
$message->streamBody(function ($chunk) {
    // Process chunk (e.g., log, save to file)
    file_put_contents('large_email.txt', $chunk, FILE_APPEND);
});

5. Using with Laravel (Service Provider)

// config/imap.php
return [
    'host' => env('IMAP_HOST'),
    'port' => env('IMAP_PORT', 993),
    'ssl' => env('IMAP_SSL', true),
    'username' => env('IMAP_USERNAME'),
    'password' => env('IMAP_PASSWORD'),
];

// app/Providers/IMAPServiceProvider.php
public function register()
{
    $this->app->singleton('imap.client', function ($app) {
        $config = $app['config']['imap'];
        $connection = new Connection($config['host'], $config['port'], $config['ssl']);
        return new Client($connection, $config['username'], $config['password']);
    });
}

6. Batch Processing

$messages = $client->getMessages('INBOX', ['UNSEEN', 'SINCE 01-Jan-2023']);
foreach ($messages as $message) {
    // Process each message (e.g., parse, store in DB)
    $this->processMessage($message);
}

Integration Tips

Laravel Mail Integration

Use tedivm/fetch alongside Laravel’s Mail facade for hybrid email handling:

// Send a mail via Laravel
Mail::to('user@example.com')->send(new WelcomeMail());

// Fetch sent emails via IMAP
$sent = $client->search('Sent', 'FROM "me@example.com"');

Event Dispatching

Wrap IMAP operations in Laravel events for observability:

// In a service class
event(new EmailFetched($message));

// In EventServiceProvider
protected $listen = [
    EmailFetched::class => [
        EmailLogger::class,
        EmailProcessor::class,
    ],
];

Caching Responses

Cache frequent IMAP queries (e.g., unread count) to reduce API calls:

$unreadCount = Cache::remember('imap.unread.count', now()->addMinutes(5), function () {
    return $client->search('INBOX', 'UNSEEN')->count();
});

Gotchas and Tips

Pitfalls

1. Connection Timeouts

  • IMAP operations can hang indefinitely. Use timeouts:
    $connection = new Connection('imap.example.com', 993, true, 30); // 30s timeout
    
  • For long-running scripts, implement retry logic with exponential backoff.

2. Memory Limits

  • Fetching large emails or attachments can exhaust memory. Use streaming:
    $message->streamBody(...); // Avoid loading entire email into memory
    

3. SSL/TLS Issues

  • Some IMAP servers require specific SSL protocols. Configure OpenSSL:
    $connection = new Connection('imap.example.com', 993, true);
    stream_context_set_option($connection->getStream(), 'ssl', [
        'verify_peer' => false, // Disable for testing (not recommended for production)
        'verify_peer_name' => false,
    ]);
    

4. Character Encoding

  • IMAP messages may use non-UTF-8 encodings. Decode properly:
    $body = mb_convert_encoding($message->getBody(), 'UTF-8', 'ISO-8859-1');
    

5. Rate Limiting

  • Aggressive polling can trigger server bans. Implement delays:
    sleep(60); // Wait 60s between checks
    

Debugging

Enable Verbose Logging

$client->setDebug(true); // Logs raw IMAP commands/responses

Check logs for malformed queries or server errors.

Handle Exceptions

Wrap IMAP calls in try-catch blocks:

try {
    $messages = $client->getMessages('INBOX');
} catch (Fetch\IMAP\Exception\ConnectionException $e) {
    Log::error('IMAP connection failed', ['error' => $e->getMessage()]);
    // Retry or notify admin
}

Common Exceptions

  • Fetch\IMAP\Exception\ConnectionException: Connection issues (host, credentials, timeout).
  • Fetch\IMAP\Exception\LoginException: Invalid username/password.
  • Fetch\IMAP\Exception\SearchException: Invalid search query.

Tips

1. Use Namespaces

Avoid naming conflicts by aliasing the package:

use Fetch\IMAP\Client as IMAPClient;

2. Leverage Laravel’s Config

Store IMAP credentials in .env:

IMAP_HOST=imap.example.com
IMAP_PORT=993
IMAP_SSL=true
IMAP_USERNAME=user@example.com
IMAP_PASSWORD=securepassword

3. Extend Message Class

Add custom methods to Fetch\IMAP\Message for domain-specific logic:

namespace App\Extensions;

use Fetch\IMAP\Message as BaseMessage;

class Message extends BaseMessage
{
    public function isPromotional()
    {
        return stripos($this->getSubject(), 'promo') !== false;
    }
}

4. Mock for Testing

Use Mockery or Laravel’s MockFacade to test IMAP interactions:

$mockClient = Mockery::mock('overload:Fetch\IMAP\Client');
$mockClient->shouldReceive('getMessages')->andReturn([$mockMessage]);

5. Performance Optimization

  • Fetch only necessary fields (e.g., BODY.PEEK[HEADER] for headers only).
  • Use getMessageIds() instead of getMessages() for large mailboxes:
    $ids = $client->getMessageIds('INBOX');
    foreach ($ids as $id) {
        $client->getMessage('INBOX', $id, ['BODY.PEEK[HEADER]']);
    }
    

6. Server-Specific Quirks

  • Some providers (e.g., Gmail) require OAuth2. Use Fetch\IMAP\OAuth2 for authentication:
    $client = new Client($connection, 'user@example.com', null, [
        'oauth' => true,
        'oauth_user_token' => 'ya29.a0Ae...',
    ]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views