Skip to content

Commit

Permalink
LDT-48: Contact Form API solution.
Browse files Browse the repository at this point in the history
  • Loading branch information
axelabhay committed Apr 29, 2024
1 parent 219c837 commit af23c4d
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Drupal/modules/custom/custom_contact_api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Contact Form API Integration

## Description:
Develop a RESTful API endpoint that enables front-end applications to submit data through the personal contact form. This endpoint will provide a seamless integration for front-end systems to interact directly with the Drupal backend without traditional form submission at /user/{uid}/contact.

## Acceptance Criteria:
- The API endpoint should accept POST requests at /api/contact-user
- The request payload must include the following fields: subject, message, and recipient inputs
- Upon successful submission, the system must send an email to the recipient (as it works for /user/{uid}/contact form)
- Include an option in the request (e.g., send_copy) that allows the sender to receive a copy of the email. If send_copy is true, send a duplicate email to the sender’s registered email address.
- Implement robust error handling to manage scenarios such as non-existent user IDs, missing field values etc..

## Solution
Course Link:
Troubleshoot:
Raise Issue: https://github.com/axelerant-trainings/project-usecases/issues/new
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: 'Custom Contact API'
type: module
description: 'Provides a REST API for submitting contact form data.'
package: Custom
core_version_requirement: ^10
dependencies:
- drupal:contact
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php

namespace Drupal\custom_contact_api\Plugin\rest\resource;

use Drupal\contact\Entity\Message;
use Drupal\contact\MailHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpFoundation\Response;

/**
* Provides a resource for submitting contact forms.
*
* @RestResource(
* id = "contact_form_submit",
* label = @Translation("Contact Form Submit"),
* uri_paths = {
* "create" = "/api/contact-user"
* }
* )
*/
class ContactFormResource extends ResourceBase {

/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* The currently authenticated user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;

/**
* The contact mail handler service.
*
* @var \Drupal\contact\MailHandlerInterface
*/
protected $mailHandler;

/**
* Constructs a ContactFormResource instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param array $serializer_formats
* The available serialization formats.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The currently authenticated user.
* @param \Drupal\contact\MailHandlerInterface $mail_handler
* The contact mail handler service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, $serializer_formats, LoggerInterface $logger, EntityTypeManagerInterface $entity_type_manager, AccountInterface $current_user, MailHandlerInterface $mail_handler)
{
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->entityTypeManager = $entity_type_manager;
$this->currentUser = $current_user;
$this->mailHandler = $mail_handler;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)
{
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('rest'),
$container->get('entity_type.manager'),
$container->get('current_user'),
$container->get('contact.mail_handler'),
);
}

/**
* Responds to POST requests.
*
* @param Symfony\Component\HttpFoundation\Request $request
* Represents an HTTP request.
*
* @return ResourceResponse
*
* @throws \Symfony\Component\HttpFoundation\Response
* When invalid data passed or server error.
*/
public function post(Request $request) {
$data = json_decode($request->getContent(), TRUE);

// For invalid inputs respond with cannot process your request message.
if (empty($data['subject']) || empty($data['message'])) {
throw new HttpException(Response::HTTP_UNPROCESSABLE_ENTITY, 'Invalid input, subject and email details missing.');
}
if (!$this->entityTypeManager->getStorage('user')->load($data['recipient'])) {
throw new HttpException(Response::HTTP_UNPROCESSABLE_ENTITY, 'Invalid input, recipient does not exists.');
}

// Create the message entity using the contact form.
$message = Message::create([
'contact_form' => 'personal',
'name' => $this->currentUser->getAccountName(),
'mail' => $this->currentUser->getEmail(),
'message' => $data['message'],
'subject' => $data['subject'],
'recipient' => $data['recipient'], // Recipient's user-id.
'copy' => isset($data['copy']) ? 1 : 0, // Send yourself a copy of the email.
]);
$message->save();

// Send Email.
try {
$this->mailHandler->sendMailMessages($message, $this->currentUser);
}
catch (\Exception $e) {
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Email could not be sent. Please try again later.');
}

return new ResourceResponse(['message' => 'Contact form submitted successfully']);
}
}
2 changes: 2 additions & 0 deletions Drupal/modules/custom/rate_limit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ To protect our public API endpoints from abuse and ensure fair usage, implement

## Solution
Course Link:
Troubleshoot:
Raise Issue: https://github.com/axelerant-trainings/project-usecases/issues/new

0 comments on commit af23c4d

Please sign in to comment.