PHP code example of cdoebler / php-generic-user-switcher

1. Go to this page and download the library: Download cdoebler/php-generic-user-switcher 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/ */

    

cdoebler / php-generic-user-switcher example snippets




use Cdoebler\GenericUserSwitcher\Generic\GenericUser;
use Cdoebler\GenericUserSwitcher\Generic\InMemoryUserProvider;
use Cdoebler\GenericUserSwitcher\Generic\SessionImpersonator;
use Cdoebler\GenericUserSwitcher\Renderer\UserSwitcherRenderer;

// 1. Create your users
$users = [
    new GenericUser(1, 'John Admin'),
    new GenericUser(2, 'Jane Developer'),
    new GenericUser(3, 'Bob Guest'),
];

// 2. Set up the user provider
$userProvider = new InMemoryUserProvider($users);

// 3. Set up the impersonator
$impersonator = new SessionImpersonator();

// 4. Render the switcher in your layout/template
$renderer = new UserSwitcherRenderer($userProvider, $impersonator);
echo $renderer->render();



// Handle user switching requests
if (isset($_GET['_switch_user'])) {
    if ($_GET['_switch_user'] === '_stop') {
        $impersonator->stopImpersonating();
    } else {
        $impersonator->impersonate($_GET['_switch_user']);
    }

    // Redirect to remove the parameter from URL
    header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
    exit;
}

// Get the current user (impersonated or real)
if ($impersonator->isImpersonating()) {
    $currentUserId = $_SESSION['generic_user_switcher_impersonator'];
    $originalUserId = $impersonator->getOriginalUserId();

    // Load the impersonated user
    $currentUser = $userProvider->findUserById($currentUserId);
} else {
    // Load the actual logged-in user
    $currentUser = getCurrentUser(); // Your app's logic
}



$users = [
    new GenericUser(1, 'Admin User'),
    new GenericUser(2, 'Regular User'),
    new GenericUser(3, 'Guest User'),
];

$provider = new InMemoryUserProvider($users);
$impersonator = new SessionImpersonator();
$renderer = new UserSwitcherRenderer($provider, $impersonator);

// Render with default options (bottom-right position)
echo $renderer->render();



echo $renderer->render([
    'position' => 'top-left',     // Options: top-left, top-right, bottom-left, bottom-right
    'z_index' => 10000,            // CSS z-index for the widget
    'param_name' => '_su',         // Custom URL parameter name
]);



// Use a custom session key for storing impersonation state
$impersonator = new SessionImpersonator('my_custom_session_key');



namespace App\UserSwitcher;

use Cdoebler\GenericUserSwitcher\Interfaces\UserInterface;
use Cdoebler\GenericUserSwitcher\Interfaces\UserProviderInterface;

class DatabaseUserProvider implements UserProviderInterface
{
    public function __construct(
        private \PDO $pdo
    ) {}

    public function getUsers(): array
    {
        $stmt = $this->pdo->query('SELECT id, name FROM users ORDER BY name');
        $users = [];

        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
            $users[] = new \Cdoebler\GenericUserSwitcher\Generic\GenericUser(
                $row['id'],
                $row['name']
            );
        }

        return $users;
    }

    public function findUserById(string|int $identifier): ?UserInterface
    {
        $stmt = $this->pdo->prepare('SELECT id, name FROM users WHERE id = ?');
        $stmt->execute([$identifier]);
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);

        if (!$row) {
            return null;
        }

        return new \Cdoebler\GenericUserSwitcher\Generic\GenericUser(
            $row['id'],
            $row['name']
        );
    }
}

// Usage
$pdo = new PDO('mysql:host=localhost;dbname=myapp', 'user', 'pass');
$provider = new DatabaseUserProvider($pdo);
$renderer = new UserSwitcherRenderer($provider, $impersonator);



namespace App\Models;

use Cdoebler\GenericUserSwitcher\Interfaces\UserInterface;

class User implements UserInterface
{
    public function __construct(
        private int $id,
        private string $email,
        private string $firstName,
        private string $lastName,
    ) {}

    public function getIdentifier(): string|int
    {
        return $this->id;
    }

    public function getDisplayName(): string
    {
        return "{$this->firstName} {$this->lastName} ({$this->email})";
    }

    // Your other user methods...
}



// app/UserSwitcher/LaravelUserProvider.php
namespace App\UserSwitcher;

use App\Models\User;
use Cdoebler\GenericUserSwitcher\Interfaces\UserInterface;
use Cdoebler\GenericUserSwitcher\Interfaces\UserProviderInterface;
use Cdoebler\GenericUserSwitcher\Generic\GenericUser;

class LaravelUserProvider implements UserProviderInterface
{
    public function getUsers(): array
    {
        return User::orderBy('name')
            ->get()
            ->map(fn($user) => new GenericUser($user->id, $user->name))
            ->all();
    }

    public function findUserById(string|int $identifier): ?UserInterface
    {
        $user = User::find($identifier);

        return $user
            ? new GenericUser($user->id, $user->name)
            : null;
    }
}

// app/Http/Middleware/HandleUserSwitcher.php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class HandleUserSwitcher
{
    public function handle(Request $request, Closure $next)
    {
        if ($request->has('_switch_user') && app()->environment('local')) {
            $impersonator = app(\Cdoebler\GenericUserSwitcher\Generic\SessionImpersonator::class);

            if ($request->get('_switch_user') === '_stop') {
                $impersonator->stopImpersonating();
            } else {
                $impersonator->impersonate($request->get('_switch_user'));
            }

            return redirect($request->url());
        }

        return $next($request);
    }
}

// resources/views/layouts/app.blade.php
@if(app()->environment('local'))
    {!! app(\Cdoebler\GenericUserSwitcher\Renderer\UserSwitcherRenderer::class)->render() !!}
@endif



// src/UserSwitcher/DoctrineUserProvider.php
namespace App\UserSwitcher;

use App\Entity\User;
use Cdoebler\GenericUserSwitcher\Generic\GenericUser;
use Cdoebler\GenericUserSwitcher\Interfaces\UserInterface;
use Cdoebler\GenericUserSwitcher\Interfaces\UserProviderInterface;
use Doctrine\ORM\EntityManagerInterface;

class DoctrineUserProvider implements UserProviderInterface
{
    public function __construct(
        private EntityManagerInterface $entityManager
    ) {}

    public function getUsers(): array
    {
        $users = $this->entityManager
            ->getRepository(User::class)
            ->findBy([], ['email' => 'ASC']);

        return array_map(
            fn(User $user) => new GenericUser($user->getId(), $user->getEmail()),
            $users
        );
    }

    public function findUserById(string|int $identifier): ?UserInterface
    {
        $user = $this->entityManager->find(User::class, $identifier);

        return $user
            ? new GenericUser($user->getId(), $user->getEmail())
            : null;
    }
}

// config/services.yaml
services:
    App\UserSwitcher\DoctrineUserProvider: ~

    Cdoebler\GenericUserSwitcher\Generic\SessionImpersonator: ~

    Cdoebler\GenericUserSwitcher\Renderer\UserSwitcherRenderer:
        arguments:
            $userProvider: '@App\UserSwitcher\DoctrineUserProvider'
            $impersonator: '@Cdoebler\GenericUserSwitcher\Generic\SessionImpersonator'

// templates/base.html.twig
{% if app.environment == 'dev' %}
    {{ render_user_switcher()|raw }}
{% endif %}



// Default session key
$impersonator = new SessionImpersonator();

// Custom session key
$impersonator = new SessionImpersonator('my_app_impersonator');

interface UserInterface
{
    public function getIdentifier(): string|int;
    public function getDisplayName(): string;
}

interface UserProviderInterface
{
    /** @return array<UserInterface> */
    public function getUsers(): array;

    public function findUserById(string|int $identifier): ?UserInterface;
}

interface ImpersonatorInterface
{
    public function impersonate(string|int $identifier): void;
    public function stopImpersonating(): void;
    public function isImpersonating(): bool;
    public function getOriginalUserId(): string|int|null;
}



// Only show switcher in development
if (getenv('APP_ENV') === 'development') {
    echo $renderer->render();
}



use Cdoebler\GenericUserSwitcher\Interfaces\AuditLoggerInterface;

class DatabaseAuditLogger implements AuditLoggerInterface
{
    public function __construct(
        private \PDO $pdo,
        private int $currentUserId
    ) {}

    public function logImpersonationStarted(string|int $targetUserId): void
    {
        $stmt = $this->pdo->prepare(
            'INSERT INTO audit_log (user_id, action, target_user_id, created_at)
             VALUES (?, ?, ?, NOW())'
        );
        $stmt->execute([$this->currentUserId, 'impersonation_started', $targetUserId]);
    }

    public function logImpersonationStopped(): void
    {
        $stmt = $this->pdo->prepare(
            'INSERT INTO audit_log (user_id, action, created_at)
             VALUES (?, ?, NOW())'
        );
        $stmt->execute([$this->currentUserId, 'impersonation_stopped']);
    }
}

// Usage
$auditLogger = new DatabaseAuditLogger($pdo, $currentUser->getId());
$impersonator = new SessionImpersonator('generic_user_switcher_impersonator', $auditLogger);
bash
composer