Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

willbrowning's avatar

Assigning user to correct team role when sending invitation

Hi,

I have added a couple of custom team roles to the sparkServiceProvider e.g:

Spark::useRoles([
            'basic' => 'Basic',
            'advanced' => 'Advanced',
        ]);

When a team owner goes to the membership page to send an email invitation to a new member. I am thinking of extending the vue component and adding a 'role' field to the spark form object so the team owner can select the role for invited users.

I will then need to add a role column to the invitations database table so that when the invitation is saved then the selected role is also saved. (Would need to edit a couple of source files here to make sure role is also saved when invitation is created).

In laravel\spark\src\Interactions\Auth\Register.php @ configureTeamForNewUser

If an invitation is present then Spark::interact(AddTeamMember::class, [$invitation->team, $user]); is called.

The handle method of laravel\spark\src\Interactions\Settings\Teams\AddTeamMember.php is:

public function handle($team, $user, $role = null)
    {
        $team->users()->attach($user, ['role' => $role ?: Spark::defaultRole()]);

        event(new TeamMemberAdded($team, $user));
    }

So as it stands no $role variable is passed to this method so it will always be Spark::defaultRole(). Will Spark::defaultRole() still be 'member' even if I have added useRoles to the sparkServiceProvider?

If I edit Auth\Register.php changing it to:

Spark::interact(AddTeamMember::class, [$invitation->team, $user, $invitation->role]);

Then I believe it should work.

However ideally I do not want to edit the source files. Is there a better way to achieve this?

Thanks

0 likes
8 replies
willbrowning's avatar

@Cronix I haven't tried that yet no. Can you use it for literally any Spark method? Also do you add Spark::swap() to the SparkServiceProvider register method?

webrgp's avatar

How about adding:


Spark::useDefaultRole('basic');

inside the booted method in SparkServiceProvider?

willbrowning's avatar

@webrgp Yes that would change the default assigned role to basic if no $role is provided. However I would still need a way to allow the team owner to choose the role they wish to assign to each member when sending the invitation email.

So that when the invited user accepts the invite they are assigned to the correct role when they register.

webrgp's avatar

Have you look into the source of /spark/resources/assets/js/settings/teams/send-invitation.js? It uses the /spark/resources/assets/js/forms/form.js.

You could extend it to allow for adding a roles dropdown.

webrgp's avatar

And you should probable create a migration adding "role" to the invitations table.

willbrowning's avatar

I've got it all working correctly, the team owner selects a role when sending the email invitation and then when this invitation is accepted the user is assigned the selected role.

I have had to edit 3 or 4 spark core files unfortunately, I've made a note of changes made so when updating I can just make them again.

I tried using the spark::swap() method to avoid editing but couldn't get it to work.

I added the following to the booted method of SparkServiceProvider:

Spark::swap('SendInvitation@handle', function ($team, $email, $role) {
            $invitedUser = Spark::user()->where('email', $email)->first();

            $this->emailInvitation(
                $invitation = $this->createInvitation($team, $email, $invitedUser, $role)
            );

            if ($invitedUser) {
                event(new UserInvitedToTeam($team, $invitedUser));
            }

            return $invitation;
        });

        Spark::swap('SendInvitation@createInvitation', function ($team, $email, $invitedUser, $role) {
            return $team->invitations()->create([
                'id' => Uuid::uuid4(),
                'user_id' => $invitedUser ? $invitedUser->id : null,
                'email' => $email,
                'role' => $role,
                'token' => str_random(40),
            ]);
        });

        Spark::swap('Register@configureTeamForNewUser', function (RegisterRequest $request, $user) {
            if ($invitation = $request->invitation()) {
                Spark::interact(AddTeamMember::class, [$invitation->team, $user, $invitation->role]);

                self::$team = $invitation->team;

                $invitation->delete();
            }

            $user->currentTeam();
        });

But it kept giving error messages, I needed to change a controller method too but I don't think this is possible with spark::swap()

Spark::swap('MailedInvitationController@store', function (CreateInvitationRequest $request, $team) {
            Spark::interact(SendInvitation::class, [$team, $request->email, $request->role]);
        });
briang's avatar

I have had to edit 3 or 4 spark core files unfortunately, I've made a note of changes made so when updating I can just make them again.

Instead of editing core files, I use a process like this.

  1. Create the same file name but in the `App' namespace.
  2. Have that file use and extend the core Spark file.
  3. Add / override any methods so it works the way I want it to.
  4. In the register method of AppServiceProvider swap out the core Spark implementation with your own, newly created one. For example: $this->app->singleton('Laravel\Spark\Contracts\Interactions\Settings\Teams\\CreateTeam', 'App\Interactions\Settings\Teams\\CreateTeam');
2 likes

Please or to participate in this conversation.