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

Rer User Bundle Laravel Package

performer/rer-user-bundle

Performer RER User Bundle is a Symfony/PHP bundle for adding user account management to RER-based applications, with ready-made user entities, authentication, registration, role handling, and admin screens to speed up secure user setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Frame it correctly first. performer/rer-user-bundle is a Symfony bundle, not a Laravel package. It has no extra.laravel block, no service provider, no vendor:publish tags. composer require performer/rer-user-bundle will succeed and then do nothing — Laravel will never boot the bundle or register its services. For a Laravel developer, "leverage" here almost always means port the domain model and semantics, not install the code.

Minimal sequence:

  1. Clone, don't require. Pull it into a scratch directory (git clone … /tmp/rer-user) or a repositories VCS entry pinned to a commit. Read it before it can pollute your composer.lock.
  2. Read in this order:
    • composer.json — PHP constraint, symfony/* and doctrine/orm versions, whether it leans on FOSUserBundle.
    • Entity/ or Model/ — the actual user fields and relations. This is the artifact you want.
    • Resources/config/doctrine/*.orm.xml (or attributes/annotations) — column names, types, lengths, unique constraints, join tables.
    • DependencyInjection/*Extension.php — role hierarchy, encoder config, registered services.
    • LICENSE, last commit date, tags. With 3 stars / 0 dependents, assume unmaintained.
  3. Write down the domain vocabulary. "RER" is undefined in the repo. If you cannot map it to a concept your business already uses, stop — a foggy core noun is a stop signal for an auth-path dependency.
  4. First use case: schema extraction. Turn the user + role + scope tables into Laravel migrations and Eloquent models, and stand up Laravel Breeze/Fortify on top of them. You get the vendor's data model with Laravel's battle-tested auth plumbing.

Aim your spike at that single deliverable. If it takes more than a couple of days, the domain is not being reused — it is being re-implemented, and you should own that decision explicitly.

Implementation Patterns

Pattern 1 — Schema-first port. Translate Doctrine mappings into migrations by hand (do not attempt to run Doctrine migrations against a Laravel database):

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('email')->unique();          // mirror length from the ORM mapping
    $table->string('password');
    $table->boolean('enabled')->default(true);  // whatever the entity calls "active"
    $table->timestamps();
    $table->softDeletes();                      // only if the entity has it
});

Schema::create('roles', fn (Blueprint $t) => [
    $t->id(), $t->string('code')->unique(), $t->string('name'),
]);

Schema::create('role_user', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained()->cascadeOnDelete();
    $table->foreignId('role_id')->constrained()->cascadeOnDelete();
    $table->primary(['user_id', 'role_id']);
});

Keep the vendor's column names where they are externally visible (reporting joins, ETL). Rename freely where they are not.

Pattern 2 — Eloquent model as the port. Wrap the schema behind a model with $hidden, casts, and a narrow role API. Never let calling code reach into a roles collection directly:

class User extends Authenticatable
{
    use Notifiable;
    protected $hidden = ['password', 'remember_token'];
    protected $casts = ['enabled' => 'bool', 'email_verified_at' => 'datetime'];

    public function roles() { return $this->belongsToMany(Role::class); }

    public function hasRole(string $code): bool
    {
        return $this->roles->contains('code', $code);
    }
}

Pattern 3 — Voters → Gates/Policies. Symfony voters operate on (attribute, subject); Laravel policies are model-bound. Port each voter as a policy method and move any multi-entity/scope logic into an explicit check:

class ReportPolicy
{
    public function view(User $user, Report $report): bool
    {
        return $user->hasRole('admin')
            || $report->scope->users()->whereKey($user->id)->exists();
    }
}

Reproduce Symfony's role hierarchy with a single Gate::before that expands inherited roles, rather than scattering hasRole chains across controllers.

Pattern 4 — Services → Actions. The bundle's "reusable user services" (register, change password, enable/disable) map cleanly onto single-purpose action classes invoked from FormRequests/controllers. Keep password hashing on Hash::make() and never port the Symfony encoder config verbatim.

Pattern 5 — Sync, if Performer is the system of record. In a Performer-based enterprise estate the user/role data often originates upstream. Model that as a queued, idempotent job that upserts users and reconciles roles — never as a live read from the vendor's tables inside a request:

class SyncUsersFromPerformer implements ShouldQueue
{
    public function handle(PerformerClient $client): void
    {
        foreach ($client->users() as $row) {
            $user = User::updateOrCreate(['email' => Str::lower($row['email'])], [...]);
            $user->roles()->sync(Role::whereIn('code', $row['roles'])->pluck('id'));
        }
    }
}

Pattern 6 — Anti-corruption layer. Even if you never install the bundle, keep the port narrow: an interface like UserDirectory / AccessResolver in your app, with the Eloquent implementation behind it. That is what makes "replace with OIDC later" a swap rather than a rewrite, and it is the only durable benefit of this evaluation.

Pattern 7 — Sidecar (last resort). A heterogeneous PHP estate can run Symfony as a separate service and expose the bundle over HTTP. Enforce one owner of the users table and one migration tool per schema. Do not attempt to boot a Symfony kernel inside a Laravel app.

Gotchas and Tips

  • composer require is a trap. It resolves, installs, and does nothing. If you only want the domain model, use a VCS repository with a pinned commit or vendor the entity classes — do not leave an unused auth-path dependency in composer.json where a scanner will flag it.
  • Doctrine ≠ Eloquent. No Data Mapper, no EntityManager, no second-level cache. $entity->setEmail() getters/setters become attributes; cascade and orphanRemoval become cascadeOnDelete and explicit deletes. Join tables with a composite primary key need $table->primary([...]).
  • Password encoders. Symfony's security.password_hashers config (algorithm, cost, migrate-on-login) has no automatic Laravel equivalent. If you are reading existing rows, verify the algorithm and cost against config/hashing.php; Symfony bcrypt cost 13 vs Laravel's default 12 will silently rehash on every login if the driver disagrees. Never accept plaintext or a homemade encoder from the bundle.
  • Role hierarchy has no Laravel analogue. Symfony's role_hierarchy implies inheritance (ROLE_ADMIN ⊃ ROLE_EDITOR ⊃ ROLE_USER). Eloquent relations do not. Implement one Gate::before that computes the transitive closure and cache it per request; otherwise you will get authorization drift that only shows up in an audit.
  • Email normalization. Symfony's canonicalizer lowercases and trims by default. If you port the schema without porting that, MySQL's utf8mb4_unicode_ci will mask the bug in dev and a utf8mb4_bin column or Postgres will expose it in production as duplicate accounts.
  • Timestamps and soft deletes. Doctrine entities frequently omit created_at/updated_at. Laravel assumes them. Either add the columns or set public $timestamps = false; — forgetting produces Unknown column 'created_at' on the first save().
  • One migration owner. Doctrine migrations and Laravel migrations must not both touch the users/roles tables. Pick Laravel and document it.
  • Scope semantics need an explicit hook. If the bundle encodes an entity/scope concept (the "RER" axis), every policy must resolve scope before granting. A policy that checks only role will pass multi-tenant tests in a single-tenant dev database.
  • Preserve extension points. The bundle's documented "extension points for custom fields" are the parts most likely to be re-implemented badly. Mirror them as interfaces in your app so adding a field later is additive.
  • Debugging without a Symfony kernel. You cannot bin/console debug:container in Laravel. If you genuinely need to inspect the bundle's wiring, run it in a throwaway Symfony skeleton and dump the container there; otherwise read DependencyInjection/ directly.
  • Pin and audit. composer audit and an explicit commit hash. With zero dependents there is no downstream pressure to patch, so assume you own every future CVE in the transitive tree.
  • Write contract tests before you swap anything. Assertations on role resolution and scope access — assertTrue($user->can('view', $scopedReport)) — are your regression net when the underlying implementation changes from "vendor semantics" to "ours."
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource