PHP code example of milenmk / laravel-email-change-confirmation

1. Go to this page and download the library: Download milenmk/laravel-email-change-confirmation library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

milenmk / laravel-email-change-confirmation example snippets




namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use MilenMk\LaravelEmailChangeConfirmation\Traits\HasEmailChangeConfirmation;

class User extends Authenticatable
{
    use HasEmailChangeConfirmation;

    // ... rest of your model
}



namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use MilenMk\LaravelEmailChangeConfirmation\Traits\HasEmailChangeConfirmation;

class User extends Authenticatable
{
    use Notifiable, HasEmailChangeConfirmation;

    // ... rest of your model
}

// In a controller
$user = auth()->user();
$user->email = '[email protected]';
$user->save(); // Email change confirmation is automatically triggered

// In a Livewire component
public function updateEmail()
{
    $this->user->email = $this->newEmail;
    $this->user->save(); // Automatically handled
}

use MilenMk\LaravelEmailChangeConfirmation\Facades\EmailChangeConfirmation;

// Request an email change
$emailChange = EmailChangeConfirmation::requestEmailChange($user, '[email protected]');

// Check pending changes
$pendingChanges = EmailChangeConfirmation::getPendingEmailChanges($user);

// Cancel pending changes
$cancelled = EmailChangeConfirmation::cancelPendingEmailChanges($user);

use MilenMk\LaravelEmailChangeConfirmation\Services\EmailChangeService;

class ProfileController extends Controller
{
    public function updateEmail(Request $request, EmailChangeService $emailChangeService)
    {
        $request->validate(['email' => 'ith('success', 'Email change confirmation sent!');
        }

        return back()->withErrors(['email' => 'Invalid email change request.']);
    }
}



namespace App\Livewire;

use Livewire\Component;

class UpdateProfile extends Component
{
    public $email;

    public function updateEmail()
    {
        $this->validate(['email' => 'dback
    }

    public function render()
    {
        return view('livewire.update-profile');
    }
}

// config/email-change-confirmation.php

return [
    // User model to use
    'user_model' => App\Models\User::class,

    // Auto-detect email changes (recommended)
    'auto_detect_email_changes' => true,

    // Route configuration
    'route_prefix' => 'email-change',
    'middleware' => ['web', 'auth', 'signed'],

    // Redirect routes after actions
    'redirect_after_confirm' => null, // e.g., 'dashboard' or 'profile.edit'
    'redirect_after_deny' => null, // e.g., 'dashboard' or 'profile.edit'
    'redirect_after_cancel' => null, // e.g., 'dashboard' or 'profile.edit'

    // Email settings
    'confirmation_email_expire_minutes' => 60,
    'from_email' => null,
    'from_name' => null,

    // Cleanup configuration
    'auto_cleanup_expired' => true,
    'cleanup_schedule' => 'hourly', // hourly, daily, weekly

    // Notification settings
    'send_notification_to_user' => true,
    'notification_message' => 'Email change confirmation sent...',

    // Email verification integration
    'auto_send_email_verification' => true,

    // Security settings
    'hash_algorithm' => 'sha256',
    'hash_secret' => env('EMAIL_CHANGE_HASH_SECRET'),
    'max_pending_changes_per_user' => 1,
    'max_requests_per_hour' => 5,
    'blocked_domains' => [],

    // Customization - override these classes
    'email_change_model' => MilenMk\LaravelEmailChangeConfirmation\Models\EmailChange::class,
    'email_change_controller' => MilenMk\LaravelEmailChangeConfirmation\Controllers\EmailChangeController::class,
    'email_change_notification' => MilenMk\LaravelEmailChangeConfirmation\Notifications\EmailChangeConfirmation::class,
    'email_change_service' => MilenMk\LaravelEmailChangeConfirmation\Services\EmailChangeService::class,

    // Livewire integration
    'livewire_enabled' => true,
    'livewire_notification_event' => 'email-change-notification',
];

// app/Console/Kernel.php

protected function schedule(Schedule $schedule)
{
    // Clean up expired email changes every hour
    $schedule->command('email-change:cleanup-expired')
        ->hourly()
        ->withoutOverlapping();

    // Or run daily at 2 AM
    $schedule->command('email-change:cleanup-expired')
        ->dailyAt('02:00')
        ->withoutOverlapping();
}

// config/email-change-confirmation.php

'auto_cleanup_expired' => true,        // Enable automatic cleanup
'cleanup_schedule' => 'hourly',        // How often to run (hourly, daily, weekly)
'confirmation_email_expire_minutes' => 60, // When requests expire



namespace App\Http\Controllers;

use MilenMk\LaravelEmailChangeConfirmation\Controllers\EmailChangeController as BaseController;
use MilenMk\LaravelEmailChangeConfirmation\Models\EmailChange;
use Illuminate\Http\RedirectResponse;

class CustomEmailChangeController extends BaseController
{
    protected function handleSuccessfulConfirmation(EmailChange $emailChange): RedirectResponse
    {
        // Custom logic after successful confirmation

        // Log the email change
        \Log::info('Email changed', [
            'user_id' => $emailChange->user_id,
            'old_email' => $emailChange->current_email,
            'new_email' => $emailChange->new_email,
        ]);

        // Send custom notification
        $emailChange->user->notify(new \App\Notifications\EmailChangedNotification());

        return parent::handleSuccessfulConfirmation($emailChange);
    }

    protected function getSuccessRedirect(): RedirectResponse
    {
        // Custom redirect logic
        return redirect()->route('profile.settings');
    }
}

// config/email-change-confirmation.php
'email_change_controller' => App\Http\Controllers\CustomEmailChangeController::class,

// config/email-change-confirmation.php

'redirect_after_confirm' => 'dashboard',     // After confirming email change
'redirect_after_deny' => 'profile.edit',    // After denying email change
'redirect_after_cancel' => 'profile.edit',  // After canceling pending change



namespace App\Notifications;

use MilenMk\LaravelEmailChangeConfirmation\Notifications\EmailChangeConfirmation as BaseNotification;
use Illuminate\Notifications\Messages\MailMessage;

class CustomEmailChangeNotification extends BaseNotification
{
    protected function buildMailMessage(string $confirmUrl, string $denyUrl): MailMessage
    {
        return (new MailMessage())
            ->subject('Confirm Your Email Change - ' . config('app.name'))
            ->greeting('Hello ' . $this->username . '!')
            ->line('We received a request to change your email address.')
            ->line('New email address: **' . $this->newEmail . '**')
            ->action('Confirm Email Change', $confirmUrl)
            ->line('If you did not request this change, please click the deny button below.')
            ->action('Deny Request', $denyUrl)
            ->line(
                'This link will expire in ' .
                    config('email-change-confirmation.confirmation_email_expire_minutes') .
                    ' minutes.',
            );
    }
}



namespace App\Services;

use MilenMk\LaravelEmailChangeConfirmation\Services\EmailChangeService as BaseService;
use Illuminate\Database\Eloquent\Model;

class CustomEmailChangeService extends BaseService
{
    public function requestEmailChange(Model $user, string $newEmail): EmailChange
    {
        // Custom validation
        if ($this->isEmailBlacklisted($newEmail)) {
            throw new \Exception('This email domain is not allowed.');
        }

        // Custom rate limiting
        if ($this->hasRecentEmailChangeAttempt($user)) {
            throw new \Exception('Please wait before requesting another email change.');
        }

        return parent::requestEmailChange($user, $newEmail);
    }

    private function isEmailBlacklisted(string $email): bool
    {
        // Your custom logic
        return false;
    }

    private function hasRecentEmailChangeAttempt(Model $user): bool
    {
        // Your custom logic
        return false;
    }
}

// Check if user has pending email changes
$user->hasPendingEmailChange(): bool

// Get pending email changes
$user->pendingEmailChanges(): HasMany

// Get latest pending email change
$user->getLatestPendingEmailChange(): ?EmailChange

// Check if user can request email change
$user->canRequestEmailChange(): bool

// Request email change
EmailChangeConfirmation::requestEmailChange($user, $newEmail): EmailChange

// Confirm email change
EmailChangeConfirmation::confirmEmailChange($emailChange): bool

// Deny email change
EmailChangeConfirmation::denyEmailChange($emailChange): bool

// Get pending changes
EmailChangeConfirmation::getPendingEmailChanges($user): Collection

// Cancel pending changes
EmailChangeConfirmation::cancelPendingEmailChanges($user): int

// Validate email change
EmailChangeConfirmation::validateEmailChange($user, $newEmail): bool

// Check status
$emailChange->isConfirmed(): bool
$emailChange->isDenied(): bool
$emailChange->isPending(): bool

// Update status
$emailChange->confirm(): bool
$emailChange->deny(): bool

    Mail::raw('Test email', function ($message) {
        $message->to('[email protected]')->subject('Test');
    });
    

use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;
    // ...
}
bash
php artisan vendor:publish --tag="email-change-confirmation-migrations"
php artisan migrate
bash
php artisan vendor:publish --tag="email-change-confirmation-config"
bash
# Generate a secure 32-byte base64-encoded secret
php -r "echo 'EMAIL_CHANGE_HASH_SECRET=' . base64_encode(random_bytes(32)) . PHP_EOL;"
blade
{{-- In your Blade template --}}
@if (auth()->user()->hasPendingEmailChange())
    @php
        $pendingChange = auth()
            ->user()
            ->getLatestPendingEmailChange();
    @endphp

    <div class="alert alert-warning">
        <strong>Pending Email Change</strong>
        <br />
        You have requested to change your email to
        <strong>{{ $pendingChange->new_email }}</strong>
        .
        <br />
        Please check your current email address ({{ $pendingChange->current_email }}) for confirmation instructions.
        <hr />
        <form method="POST" action="{{ route('email-change-confirmation.cancel-pending') }}" class="d-inline">
            @csrf
            <button type="submit" class="btn btn-sm btn-outline-danger">Cancel Request</button>
        </form>
    </div>
@endif
bash
# Run cleanup synchronously
php artisan email-change:cleanup-expired

# Dispatch cleanup job to queue
php artisan email-change:cleanup-expired --queue