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

Email Concealer Laravel Package

spatie/email-concealer

Replaces email domains in any string (e.g., dumps) to safely use production data locally without real addresses. Create a Concealer and call conceal(): info@spatie.be becomes info@example.com. Simple, fast, and handy for anonymizing text.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/email-concealer
    

    No additional configuration is required—just require the package in your project.

  2. First Use Case: Replace visible emails in strings (e.g., logs, dumps, or public-facing content) with masked versions:

    use Spatie\EmailConcealer\Concealer;
    
    $concealer = Concealer::create();
    $maskedEmail = $concealer->conceal('contact@example.com');
    // Returns: "contact@example.com" (default mask) or custom placeholder if configured.
    
  3. Where to Look First:

    • Concealer class: Core functionality for masking emails.
    • Concealer::create(): Static factory method to instantiate the concealer.
    • conceal() method: Primary method to process strings.

Implementation Patterns

Core Workflows

  1. Basic Masking: Replace all emails in a string with a default placeholder (e.g., example.com):

    $concealer = Concealer::create();
    $text = "Emails: user@domain.com, admin@test.org";
    echo $concealer->conceal($text);
    // Output: "Emails: user@example.com, admin@example.com"
    
  2. Custom Placeholders: Override the default domain (e.g., for testing):

    $concealer = Concealer::create('masked.test');
    $concealer->conceal('user@domain.com');
    // Output: "user@masked.test"
    
  3. Integration with Laravel:

    • Blade Templates: Use a helper or directive to auto-conceal emails in views:
      // app/Helpers/EmailHelper.php
      if (!function_exists('concealEmail')) {
          function concealEmail($email) {
              return Concealer::create()->conceal($email);
          }
      }
      
      {{ concealEmail('user@domain.com') }}
      
    • Eloquent Observers: Mask emails in retrieved events for sensitive data:
      use Spatie\EmailConcealer\Concealer;
      
      class UserObserver {
          public function retrieved($user) {
              $user->email = Concealer::create()->conceal($user->email);
          }
      }
      
  4. Batch Processing: Mask emails in arrays or collections:

    $emails = ['a@test.com', 'b@work.org'];
    $masked = array_map([Concealer::create(), 'conceal'], $emails);
    // ['a@example.com', 'b@example.com']
    
  5. Regex Patterns: Extend the default regex to handle edge cases (e.g., subdomains):

    $concealer = Concealer::create();
    $concealer->setRegex('/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/i');
    

Gotchas and Tips

Pitfalls

  1. Regex Limitations:

    • The default regex may miss emails with unusual formats (e.g., user+tag@sub.domain.co.uk).
    • Fix: Customize the regex or pre-process strings to standardize email formats.
  2. Case Sensitivity:

    • The regex is case-insensitive by default, but some edge cases (e.g., User@DOMAIN.COM) might behave unexpectedly.
    • Tip: Use strtolower() on input strings if consistency is critical.
  3. Performance:

    • Processing large texts (e.g., database dumps) with many emails can be slow.
    • Optimization: Cache the Concealer instance or use Laravel’s Str::of() for chained operations:
      Str::of($largeText)->replaceMatches('/\b[\w.%+-]+@[\w.-]+\.\w+\b/i', function ($match) {
          return Concealer::create()->conceal($match);
      });
      
  4. False Positives:

    • Non-email strings (e.g., "user@domain") may be incorrectly masked.
    • Solution: Tighten the regex or add validation:
      if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
          return Concealer::create()->conceal($email);
      }
      

Debugging

  • Log Masked Outputs: Verify replacements by logging the output:
    \Log::debug('Masked:', ['email' => $concealer->conceal($email)]);
    
  • Test Edge Cases: Validate with:
    • Internationalized emails (e.g., 用户@例子.测试).
    • Emails with quotes (e.g., "user name"@domain.com).

Extension Points

  1. Custom Concealer Classes: Extend the Concealer class to add logic (e.g., logging masked emails):

    class CustomConcealer extends \Spatie\EmailConcealer\Concealer {
        public function conceal($string) {
            $masked = parent::conceal($string);
            \Log::info("Email masked: $string => $masked");
            return $masked;
        }
    }
    
  2. Service Provider Binding: Bind the concealer to Laravel’s container for dependency injection:

    // app/Providers/AppServiceProvider.php
    public function register() {
        $this->app->singleton(Concealer::class, function () {
            return Concealer::create('app.test');
        });
    }
    

    Then inject it into controllers/services:

    use Spatie\EmailConcealer\Concealer;
    
    class UserController {
        public function __construct(private Concealer $concealer) {}
    }
    
  3. Environment-Specific Config: Use Laravel’s config to switch masking behavior:

    // config/email-concealer.php
    return [
        'placeholder' => env('EMAIL_MASK_PLACEHOLDER', 'example.com'),
        'enabled' => env('EMAIL_MASK_ENABLED', true),
    ];
    

    Then conditionally apply masking:

    if (config('email-concealer.enabled')) {
        $concealer = Concealer::create(config('email-concealer.placeholder'));
    }
    

Pro Tips

  • Combine with laravel-debugbar: Add a tab to visualize masked emails in development.
  • Use in Migrations: Mask emails in seed data or fixtures to avoid hardcoding real addresses.
  • Localization: Support non-English domains by extending the regex or using a library like egulias/email-validator.
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport