Skip to content

Commit

Permalink
PROD-29995: Implement EDA event for when a user completes the process…
Browse files Browse the repository at this point in the history
… for account registration
  • Loading branch information
tregismoreira authored and ribel committed Nov 1, 2024
1 parent 4c554b6 commit b38d44e
Show file tree
Hide file tree
Showing 8 changed files with 731 additions and 14 deletions.
2 changes: 1 addition & 1 deletion modules/custom/social_eda/src/Types/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static function fromId(string $id): self {
'name' => 'Cron',
],
'graphql' => [
'uuid' => '123e4567-e89b-12d3-a456-426614174001',
'uuid' => 'fd4b26f6-ec5e-47c2-8bf1-d8db7fc9d094',
'name' => 'GraphQL',
],
];
Expand Down
21 changes: 8 additions & 13 deletions modules/social_features/social_event/src/EdaHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ final class EdaHandler {
* {@inheritDoc}
*/
public function __construct(
private readonly DispatcherInterface $dispatcher,
private readonly ?DispatcherInterface $dispatcher,
private readonly UuidInterface $uuid,
private readonly RequestStack $requestStack,
private readonly ModuleHandlerInterface $moduleHandler,
Expand Down Expand Up @@ -193,17 +193,12 @@ private function determineActors(): array {
$application = NULL;
$user = NULL;

switch ($this->routeName) {
case 'entity.node.edit_form':
case 'entity.node.delete_form':
case 'entity.node.delete_multiple_form':
case 'system.admin_content':
$user = $this->currentUser;
break;

case 'entity.ultimate_cron_job.run':
$application = 'cron';
break;
if ($this->currentUser instanceof UserInterface) {
$user = $this->currentUser;
}

if ($this->routeName == 'entity.ultimate_cron_job.run') {
$application = 'cron';
}

return [
Expand All @@ -229,7 +224,7 @@ private function determineActors(): array {
*/
private function dispatch(string $topic_name, string $event_type, NodeInterface $node, string $op = ''): void {
// Skip if required modules are not enabled.
if (!$this->moduleHandler->moduleExists('social_eda')) {
if (!$this->moduleHandler->moduleExists('social_eda') || !$this->dispatcher) {
return;
}

Expand Down
142 changes: 142 additions & 0 deletions modules/social_features/social_user/asyncapi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
channels:
userCreate:
address: com.getopensocial.cms.user.create
messages:
userCreate:
payload:
allOf:
- $ref: '#/components/schemas/cloudEventsSchema'
- type: object
properties:
data:
type: object
properties:
id:
type: string
description: The UUID of the user.
created:
type: string
format: date-time
description: The creation time of the user.
updated:
type: string
format: date-time
description: The last updated time of the user.
status:
type: string
description: The status of the user.
enum:
- active
- blocked
displayName:
type: string
description: The display name of the user.
firstName:
type: string
nullable: true
description: The first name of the user.
lastName:
type: string
nullable: true
description: The last name of the user.
email:
type: string
format: email
description: The email address of the user.
roles:
type: array
items:
type: string
description: Roles assigned to the user.
timezone:
type: string
description: The timezone of the user.
language:
type: string
description: The preferred language of the user.
address:
type: object
nullable: true
properties:
label:
type: string
description: The label of the user address.
countryCode:
type: string
description: The country code of the user address.
administrativeArea:
type: string
description: The administrative area of the user address.
locality:
type: string
description: The locality of the user address.
dependentLocality:
type: string
description: The dependent locality of the user address.
postalCode:
type: string
description: The postal code of the user address.
sortingCode:
type: string
description: The sorting code of the user address.
addressLine1:
type: string
description: The first address line of the user address.
addressLine2:
type: string
description: The second address line of the user address.
phone:
type: string
nullable: true
description: The phone number of the user.
function:
type: string
nullable: true
description: The job function of the user.
organization:
type: string
nullable: true
description: The organization of the user.
href:
type: object
properties:
canonical:
type: string
format: uri
description: Canonical URL of the user.
actor:
type: object
properties:
application:
type: object
nullable: true
properties:
id:
type: string
description: The UUID of the application.
name:
type: string
description: The name of the application.
user:
type: object
nullable: true
properties:
id:
type: string
description: The UUID of the actor user.
displayName:
type: string
description: The display name of the actor user.
href:
type: object
properties:
canonical:
type: string
format: uri
description: Canonical URL of the actor user.

operations:
onUserCreate:
action: 'receive'
channel:
$ref: '#/channels/userCreate'
51 changes: 51 additions & 0 deletions modules/social_features/social_user/social_user.module
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
Expand Down Expand Up @@ -714,6 +715,56 @@ function social_user_user_insert(UserInterface $user): void {
}
}

/**
* Implements hook_ENTITY_TYPE_insert().
*
* When a new Profile entity is created (if it does not require admin approval),
* we should trigger the EDA event.
*/
function social_user_profile_insert(ProfileInterface $profile): void {
$user = $profile->get('uid')->entity;
$current_request = \Drupal::requestStack()->getCurrentRequest();
$user_settings = \Drupal::config('user.settings');
$trigger = FALSE;

// If user is created from the route `user.register`.
if ($current_request && $current_request->get('_route') == 'user.register') {
// Admin approval is required.
if ($user_settings->get('register') != 'visitors_admin_approval') {
$trigger = TRUE;
}
}
else {
$trigger = TRUE;
}

if ($trigger && $user instanceof UserInterface) {
\Drupal::service('social_user.eda_handler')->userCreate($user);
}
}

/**
* Implements hook_ENTITY_TYPE_update().
*
* When the user account is created but depends on admin approval,
* we must use the hook_ENTITY_TYPE_update() to capture the status change
* so that we can trigger the EDA event.
*/
function social_user_user_update(EntityInterface $entity): void {
// Make sure the updated entity is a user entity.
if ($entity instanceof UserInterface) {
$original = $entity->original;

// Status changed to active.
if ($entity->isActive() && $original instanceof UserInterface && $original->isBlocked()) {
// The user never logged in & the created time is equals to changed time.
if ($entity->getLastLoginTime() == 0 && $original->getCreatedTime() == $original->getChangedTime()) {
\Drupal::service('social_user.eda_handler')->userCreate($entity);
}
}
}
}

/**
* Implements hook_views_data_alter().
*/
Expand Down
5 changes: 5 additions & 0 deletions modules/social_features/social_user/social_user.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ services:
arguments: ['@current_route_match', '@current_user', '@config.factory']
tags:
- { name: event_subscriber }
social_user.eda_handler:
autowire: true
class: Drupal\social_user\EdaHandler
tags:
- { name: social.eda.handler }
Loading

0 comments on commit b38d44e

Please sign in to comment.