Weave 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(): [email protected] becomes [email protected]. 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('[email protected]');
    // Returns: "[email protected]" (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: [email protected], [email protected]";
    echo $concealer->conceal($text);
    // Output: "Emails: [email protected], [email protected]"
    
  2. Custom Placeholders: Override the default domain (e.g., for testing):

    $concealer = Concealer::create('masked.test');
    $concealer->conceal('[email protected]');
    // Output: "[email protected]"
    
  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('[email protected]') }}
      
    • 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 = ['[email protected]', '[email protected]'];
    $masked = array_map([Concealer::create(), 'conceal'], $emails);
    // ['[email protected]', '[email protected]']
    
  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., [email protected]).
    • 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., [email protected]) 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.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk