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

Newsletters Laravel Package

laravelir/newsletters

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laravelir/newsletters
    php artisan vendor:publish --provider="Laravelir\Newsletters\Providers\NewslettersServiceProvider"
    
    • This publishes the migration, config, and views to your project.
  2. Run Migrations:

    php artisan migrate
    
    • Creates the newsletters and subscribers tables.
  3. First Use Case:

    • Create a Subscription Form: Use the provided Blade view (resources/views/vendor/newsletters/subscribe.blade.php) or extend it:
      @include('newsletters::subscribe', ['newsletter' => $newsletter])
      
    • Subscribe a User:
      use Laravelir\Newsletters\Facades\Newsletter;
      
      $newsletter = Newsletter::findOrCreate('weekly-updates');
      $subscriber = $newsletter->subscribe('user@example.com');
      
    • Send a Newsletter:
      $newsletter->send('Welcome!', 'emails.newsletter.welcome', ['data' => 'value']);
      

Where to Look First

  • Config File: config/newsletters.php (published via php artisan laravelir:newsletters).
    • Define default newsletter settings (e.g., default_from_address, queue_driver).
  • Migrations: database/migrations/xxxx_create_newsletters_tables.php.
    • Understand the schema for newsletters (e.g., name, subject, body) and subscribers (e.g., email, newsletter_id).
  • Facade: Laravelir\Newsletters\Facades\Newsletter.
    • Central entry point for all newsletter operations.

Implementation Patterns

Core Workflows

  1. Managing Newsletters:

    • Create/Update:
      $newsletter = Newsletter::create([
          'name' => 'monthly-digest',
          'subject' => 'Monthly Update',
          'body' => 'Your monthly content here.',
      ]);
      
    • Find/Query:
      $newsletter = Newsletter::find('weekly-updates');
      $newsletters = Newsletter::where('active', true)->get();
      
  2. Subscriber Management:

    • Subscribe/Unsubscribe:
      $subscriber = $newsletter->subscribe('user@example.com');
      $subscriber->unsubscribe(); // Soft deletes the subscriber
      
    • Bulk Actions:
      $newsletter->subscribers()->where('confirmed', false)->confirm();
      
  3. Sending Newsletters:

    • Basic Send:
      $newsletter->send('Subject', 'emails.newsletter.template', ['key' => 'value']);
      
    • Queue for Later:
      $newsletter->queue('Subject', 'emails.newsletter.template', ['key' => 'value']);
      
    • Custom From Address:
      $newsletter->send('Subject', 'template', [], ['from' => 'custom@email.com']);
      
  4. Confirmation Workflow:

    • Generate Confirmation Token:
      $token = $subscriber->createConfirmationToken();
      
    • Confirm Subscription:
      $subscriber->confirm($token);
      
    • Handle Confirmation Links:
      <a href="{{ route('newsletters.confirm', $token) }}">Confirm Subscription</a>
      
      • Route definition (add to routes/web.php):
        Route::get('/newsletters/confirm/{token}', [\Laravelir\Newsletters\Http\Controllers\NewsletterController::class, 'confirm']);
        
  5. Event Listeners:

    • Listen for subscriber events (e.g., Subscribed, Unsubscribed):
      use Laravelir\Newsletters\Events\Subscribed;
      
      event(new Subscribed($subscriber));
      
    • Publish events in EventServiceProvider:
      protected $listen = [
          Subscribed::class => [
              'App\Listeners\LogSubscriberActivity',
          ],
      ];
      

Integration Tips

  • Mail Templates:
    • Store templates in resources/views/emails/newsletter/.
    • Use shared views or extend the package’s default templates.
  • Queue System:
    • Configure newsletters.queue_driver in config/newsletters.php (e.g., database, redis).
    • Process queued newsletters with:
      php artisan queue:work
      
  • API Endpoints:
    • Use the package’s HTTP controllers or build custom APIs:
      Route::post('/api/subscribe', [\App\Http\Controllers\NewsletterController::class, 'subscribe']);
      
  • Testing:
    • Mock the Newsletter facade or use in-memory databases for tests:
      $this->partialMock(Newsletter::class, function ($mock) {
          $mock->shouldReceive('send')->once();
      });
      

Gotchas and Tips

Pitfalls

  1. Migration Conflicts:

    • If you modify the package’s migrations, do not edit the published files directly. Instead:
      • Copy the migration to your database/migrations/ folder.
      • Modify the copied file and run php artisan migrate:fresh.
    • Tip: Use php artisan vendor:publish --tag=migrations to republish if needed.
  2. Queue Stuck Jobs:

    • Queued newsletter jobs may fail silently. Monitor with:
      php artisan queue:failed
      
    • Fix: Retry or delete failed jobs:
      php artisan queue:retry <job-id>
      php artisan queue:flush
      
  3. Double Subscriptions:

    • The package does not enforce uniqueness by default. Add a unique constraint in the subscribers table:
      Schema::table('subscribers', function (Blueprint $table) {
          $table->unique(['email', 'newsletter_id']);
      });
      
    • Tip: Use upsert in your subscription logic:
      $subscriber = Subscriber::upsert(
          ['email' => 'user@example.com', 'newsletter_id' => $newsletter->id],
          ['email']
      );
      
  4. Email Bounces:

    • The package lacks built-in bounce handling. Integrate with a service like Mailgun or SendGrid for bounce webhooks.
    • Tip: Add a bounced_at column to the subscribers table and automate cleanup:
      $subscriber->update(['bounced_at' => now()]);
      
  5. Performance with Large Subscriber Lists:

    • Sending to thousands of subscribers may time out. Use chunking:
      $subscribers = $newsletter->subscribers()->cursor();
      foreach ($subscribers->chunk(100) as $chunk) {
          foreach ($chunk as $subscriber) {
              Mail::to($subscriber->email)->send(new NewsletterMail($newsletter));
          }
      }
      

Debugging

  1. Log Subscriber Activity:

    • Enable logging in config/newsletters.php:
      'log_subscribers' => true,
      
    • Check logs at storage/logs/laravel.log.
  2. Verify Tokens:

    • Confirmation tokens may expire. Extend the Subscribers model:
      protected static function boot() {
          parent::boot();
          static::creating(function ($subscriber) {
              $subscriber->confirmation_token = Str::random(60);
              $subscriber->confirmation_expires_at = now()->addDays(7);
          });
      }
      
  3. Test Email Delivery:

    • Use Laravel’s MailFake for testing:
      use Illuminate\Mail\Testing\Mails;
      
      public function test_newsletter_send() {
          $this->withoutExceptionHandling();
          $newsletter = Newsletter::create([...]);
          $newsletter->send('Test', 'template');
      
          $this->assertCount(1, Mail::failures());
      }
      

Extension Points

  1. Custom Subscriber Fields:

    • Extend the subscribers table:
      Schema::table('subscribers', function (Blueprint $table) {
          $table->string('first_name')->nullable();
          $table->string('last_name')->nullable();
      });
      
    • Update the Subscriber model:
      protected $fillable = ['email', 'newsletter_id', 'first_name', 'last_name'];
      
  2. Custom Newsletter Types:

    • Add a type column to the newsletters table and filter accordingly:
      $newsletter = Newsletter::where('type', 'promotional')->first();
      
  3. Override Views:

    • Publish and override the package’s views:
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours