If a user successfully gets connected via a given provider, you're able to map some data to your user entity.
For example, if you're using a Google client, there are some properties you may want to use (email
, name
).
Since every client may vary in naming of properties, you also may want to adjust the mapping. Just use a EventListener to do so.
If there is no registered event listener, Members tries to map some default fields by guessing all properties by method_exists()
.
There are some invalid properties: 'lastLogin', 'password', 'confirmationToken', 'passwordRequestedAt', 'groups', 'ssoIdentities'.
However, if you're adding your own EventListener, the mapping is totally up to you. There are two different types of mapping events:
The OAUTH_RESOURCE_MAPPING_PROFILE
event occurs before a SSO Identity gets assigned to given user profile.
This Event fires shortly before the SSO Identity gets applied to the user.
Attention: This event also fires after an existing user gets connected to a client. You may don't want to override existing values!
The OAUTH_RESOURCE_MAPPING_REGISTRATION
event occurs before the registration form gets rendered
(Only available if integration type is complete_profile
).
First, add your service:
<?php
namespace App\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use MembersBundle\Adapter\User\UserInterface;
use MembersBundle\Event\OAuth\OAuthResourceEvent;
use MembersBundle\MembersEvents;
class MembersResourceMappingListener implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
MembersEvents::OAUTH_RESOURCE_MAPPING_PROFILE => 'onProfileMapping',
MembersEvents::OAUTH_RESOURCE_MAPPING_REGISTRATION => 'onRegistrationMapping',
MembersEvents::OAUTH_RESOURCE_MAPPING_REFRESH => 'onRegistrationRefresh',
];
}
public function onProfileMapping(OAuthResourceEvent $event): void
{
$user = $event->getUser();
$resourceOwner = $event->getResourceOwner();
$ownerDetails = $resourceOwner->toArray();
$this->mapData($user, $ownerDetails);
}
public function onRegistrationMapping(OAuthResourceEvent $event): void
{
$user = $event->getUser();
$resourceOwner = $event->getResourceOwner();
$ownerDetails = $resourceOwner->toArray();
$this->mapData($user, $ownerDetails);
}
public function onRegistrationRefresh(OAuthResourceRefreshEvent $event): void
{
$user = $event->getUser();
$resourceOwner = $event->getResourceOwner();
$ownerDetails = $resourceOwner->toArray();
$user->setUserName($ownerDetails['name']);
// ATTENTION! You need to inform event about changes!
$event->setHasChanged(true);
}
protected function mapData(UserInterface $user, array $ownerDetails): void
{
if (empty($user->getEmail()) && isset($ownerDetails['email'])) {
$user->setEmail($ownerDetails['email']);
}
if (empty($user->getUserName()) && isset($ownerDetails['name'])) {
$user->setUserName($ownerDetails['name']);
}
}
}
Then, register it:
App\EventListener\MembersResourceMappingListener:
autowire: true
tags:
- { name: kernel.event_subscriber }