Skip to content
Snippets Groups Projects
Commit 6e3cd775 authored by Patrick Kenny's avatar Patrick Kenny
Browse files

Issue #3446595 by ptmkenny: Use interface for FirebasePhpMessagingService and fix coding standards

parent 82f2bdef
No related branches found
No related tags found
1 merge request!5use interface for FirebasePhpMessagingService and fix coding standards
Pipeline #170246 passed with warnings
<?php
namespace Drupal\firebase_php;
use Kreait\Firebase\Messaging\MulticastSendReport;
use Kreait\Firebase\Messaging\Notification;
/**
* Provides an interface for working with the Firebase PHP Messaging Service.
*
* THIS MODULE IS IN DEVELOPMENT AND THIS API WILL CHANGE!
*/
interface FirebasePhpMessagingServiceInterface {
/**
* Creates a notification for use in sending messages.
*
* All messages need a notification.
*
* @param string $title
* The title of the notification.
* @param string $body
* The body of the notification.
* @param string|null $url
* The optional URL for the notification.
*
* @return \Kreait\Firebase\Messaging\Notification
* The notification.
*/
public function createNotification(string $title, string $body, ?string $url = NULL): Notification;
/**
* Sends a message to a single device.
*
* @param string $deviceToken
* The token of the device to send a message to.
* @param \Kreait\Firebase\Messaging\Notification $notification
* The notification to send.
* @param int|null $badge_count
* The optional badge count for the device.
* @param array $data
* The optional data.
* @param array $apns_data
* The optional APNS data.
*/
public function sendMessageSingleDevice(string $deviceToken, Notification $notification, ?int $badge_count = NULL, array $data = [], array $apns_data = []): void;
/**
* Sends a message to a topic.
*
* @param string $topic
* The topic.
* @param \Kreait\Firebase\Messaging\Notification $notification
* The notification to send.
* @param int|null $badge_count
* The optional badge count.
* @param array $data
* The optional data.
* @param array $apns_data
* The optional APNS data.
*/
public function sendMessageTopic(string $topic, Notification $notification, ?int $badge_count = NULL, array $data = [], array $apns_data = []): void;
/**
* Sends a single message to multiple devices.
*
* @param array $deviceTokens
* An array of all the device tokens to send the message to.
* @param \Kreait\Firebase\Messaging\Notification $notification
* The notification to send.
* @param int|null $badge_count
* The optional badge count.
* @param array $data
* The optional data.
* @param array $apns_data
* The optional APNS data.
*
* @return \Kreait\Firebase\Messaging\MulticastSendReport
* A report of message showing whether message sending succeeded or failed.
*/
public function sendMessageMultipleDevices(array $deviceTokens, Notification $notification, ?int $badge_count = NULL, array $data = [], array $apns_data = []): MulticastSendReport;
}
...@@ -45,10 +45,10 @@ class FirebasePhpConfigurationForm extends ConfigFormBase { ...@@ -45,10 +45,10 @@ class FirebasePhpConfigurationForm extends ConfigFormBase {
'#title' => $this->t('Credentials Path'), '#title' => $this->t('Credentials Path'),
'#description' => $this->t( '#description' => $this->t(
'The path to the JSON credentials file. SECURITY WARNING: This file MUST be outside the Drupal webroot. The path may be absolute (e.g., %abs), relative to the Drupal directory (e.g., %rel), or defined using a stream wrapper (e.g., %str).', [ 'The path to the JSON credentials file. SECURITY WARNING: This file MUST be outside the Drupal webroot. The path may be absolute (e.g., %abs), relative to the Drupal directory (e.g., %rel), or defined using a stream wrapper (e.g., %str).', [
'%abs' => '/etc/foobar.json', '%abs' => '/etc/foobar.json',
'%rel' => '../firebase/foobar.json', '%rel' => '../firebase/foobar.json',
'%str' => 'private://firebase/foobar.json', '%str' => 'private://firebase/foobar.json',
]), ]),
'#default_value' => $config->get(self::KEY_CREDENTIALS_PATH), '#default_value' => $config->get(self::KEY_CREDENTIALS_PATH),
'#required' => TRUE, '#required' => TRUE,
]; ];
......
...@@ -7,34 +7,42 @@ namespace Drupal\firebase_php\Form; ...@@ -7,34 +7,42 @@ namespace Drupal\firebase_php\Form;
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\firebase_php\Exception\FirebasePhpException; use Drupal\firebase_php\Exception\FirebasePhpException;
use Drupal\firebase_php\Service\FirebasePhpMessagingService; use Drupal\firebase_php\FirebasePhpMessagingServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/** /**
* Provides a form to send a test push notification. * Provides a form to send a test push notification.
*/ */
final class FirebasePhpSendTestMessageForm extends FormBase { final class FirebasePhpSendTestMessageForm extends FormBase {
/** /**
* Returns a unique string identifying the form. * The Firebase PHP messaging service from this module.
*
* The returned ID should be a unique string that can be a valid PHP function
* name, since it's used in hook implementation names such as
* hook_form_FORM_ID_alter().
* *
* @return string * @var \Drupal\firebase_php\FirebasePhpMessagingServiceInterface
* The unique string identifying the form. */
protected FirebasePhpMessagingServiceInterface $messagingService;
public function __construct(FirebasePhpMessagingServiceInterface $messagingService) {
$this->messagingService = $messagingService;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('firebase_php.messaging')
);
}
/**
* {@inheritdoc}
*/ */
public function getFormId(): string { public function getFormId(): string {
return 'firebase_php_send_test_message_form'; return 'firebase_php_send_test_message_form';
} }
/** /**
* Form constructor. * {@inheritdoc}
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/ */
public function buildForm(array $form, FormStateInterface $form_state): array { public function buildForm(array $form, FormStateInterface $form_state): array {
$form['title'] = [ $form['title'] = [
...@@ -73,19 +81,12 @@ final class FirebasePhpSendTestMessageForm extends FormBase { ...@@ -73,19 +81,12 @@ final class FirebasePhpSendTestMessageForm extends FormBase {
} }
/** /**
* Form submission handler. * {@inheritdoc}
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*/ */
public function submitForm(array &$form, FormStateInterface $form_state): void { public function submitForm(array &$form, FormStateInterface $form_state): void {
try { try {
/** @var \Drupal\firebase_php\Service\FirebasePhpMessagingService $messaging_service */ $notification = $this->messagingService->createNotification($form_state->getValue('title'), $form_state->getValue('message'));
$messaging_service = \Drupal::service('firebase_php.messaging'); $this->messagingService->sendMessageSingleDevice($form_state->getValue('device_token'), $notification);
$notification = $messaging_service->createNotification($form_state->getValue('title'), $form_state->getValue('message'));
$messaging_service->sendMessageSingleDevice($form_state->getValue('device_token'), $notification);
} }
catch (\Exception $e) { catch (\Exception $e) {
throw new FirebasePhpException($e->getMessage(), 0, $e); throw new FirebasePhpException($e->getMessage(), 0, $e);
......
...@@ -3,26 +3,39 @@ ...@@ -3,26 +3,39 @@
namespace Drupal\firebase_php\Service; namespace Drupal\firebase_php\Service;
use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\firebase_php\Exception\FirebasePhpCredentialsNotFoundException; use Drupal\firebase_php\Exception\FirebasePhpCredentialsNotFoundException;
use Drupal\firebase_php\Exception\FirebasePhpInvalidArgumentException; use Drupal\firebase_php\Exception\FirebasePhpInvalidArgumentException;
use Drupal\firebase_php\FirebasePhpMessagingServiceInterface;
use Drupal\firebase_php\Form\FirebasePhpConfigurationForm; use Drupal\firebase_php\Form\FirebasePhpConfigurationForm;
use Kreait\Firebase\Factory;
use Drupal\Core\Logger\LoggerChannelInterface;
use Kreait\Firebase\Contract\Messaging; use Kreait\Firebase\Contract\Messaging;
use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\ApnsConfig; use Kreait\Firebase\Messaging\ApnsConfig;
use Kreait\Firebase\Messaging\CloudMessage; use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Message; use Kreait\Firebase\Messaging\Message;
use Kreait\Firebase\Messaging\Notification;
use Kreait\Firebase\Messaging\MulticastSendReport; use Kreait\Firebase\Messaging\MulticastSendReport;
use Kreait\Firebase\Messaging\Notification;
/** /**
* Service for pushing messages to mobile devices using Firebase PHP. * Service for pushing messages to mobile devices using Firebase PHP.
*/ */
class FirebasePhpMessagingService { class FirebasePhpMessagingService implements FirebasePhpMessagingServiceInterface {
/**
* The messaging service from the Firebase PHP Admin SDK.
*
* @var \Kreait\Firebase\Contract\Messaging
*/
protected Messaging $messaging; protected Messaging $messaging;
protected $config; /**
* This module's configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected ImmutableConfig $config;
public function __construct( public function __construct(
protected LoggerChannelInterface $logger, protected LoggerChannelInterface $logger,
...@@ -31,7 +44,7 @@ class FirebasePhpMessagingService { ...@@ -31,7 +44,7 @@ class FirebasePhpMessagingService {
) { ) {
$config = $this->configFactory->get('firebase_php.settings'); $config = $this->configFactory->get('firebase_php.settings');
$credentials = $config->get(FirebasePhpConfigurationForm::KEY_CREDENTIALS_PATH); $credentials = $config->get(FirebasePhpConfigurationForm::KEY_CREDENTIALS_PATH);
if ($credentials === null) { if ($credentials === NULL) {
throw new FirebasePhpCredentialsNotFoundException( throw new FirebasePhpCredentialsNotFoundException(
"Failed to get Firebase credentials!", "Failed to get Firebase credentials!",
); );
...@@ -42,11 +55,17 @@ class FirebasePhpMessagingService { ...@@ -42,11 +55,17 @@ class FirebasePhpMessagingService {
$this->config = $config; $this->config = $config;
} }
public function createNotification(string $title, string $body, ?string $url = null): Notification { /**
* {@inheritdoc}
*/
public function createNotification(string $title, string $body, ?string $url = NULL): Notification {
return Notification::create($title, $body, $url); return Notification::create($title, $body, $url);
} }
public function sendMessageSingleDevice(string $deviceToken, Notification $notification, ?int $badge_count = null, array $data = [], array $apns_data = []): void { /**
* {@inheritdoc}
*/
public function sendMessageSingleDevice(string $deviceToken, Notification $notification, ?int $badge_count = NULL, array $data = [], array $apns_data = []): void {
$message = $this->createMessageFromNotificationAndAddBadge($notification, $badge_count, $deviceToken, $data, $apns_data); $message = $this->createMessageFromNotificationAndAddBadge($notification, $badge_count, $deviceToken, $data, $apns_data);
$this->messaging->send($message); $this->messaging->send($message);
...@@ -56,8 +75,11 @@ class FirebasePhpMessagingService { ...@@ -56,8 +75,11 @@ class FirebasePhpMessagingService {
]); ]);
} }
public function sendMessageTopic(string $topic, Notification $notification, ?int $badge_count = null, array $data = [], array $apns_data = []): void { /**
$message = $this->createMessageFromNotificationAndAddBadge($notification, $badge_count, null, $data, $apns_data, $topic); * {@inheritdoc}
*/
public function sendMessageTopic(string $topic, Notification $notification, ?int $badge_count = NULL, array $data = [], array $apns_data = []): void {
$message = $this->createMessageFromNotificationAndAddBadge($notification, $badge_count, NULL, $data, $apns_data, $topic);
$this->messaging->send($message); $this->messaging->send($message);
$this->logger->notice('Sending push notification for user @uid to topic @topic.', [ $this->logger->notice('Sending push notification for user @uid to topic @topic.', [
...@@ -66,11 +88,14 @@ class FirebasePhpMessagingService { ...@@ -66,11 +88,14 @@ class FirebasePhpMessagingService {
]); ]);
} }
public function sendMessageMultipleDevices(array $deviceTokens, Notification $notification, ?int $badge_count = null, array $data = [], array $apns_data = []): MulticastSendReport { /**
$message = $this->createMessageFromNotificationAndAddBadge($notification, $badge_count, null, $data, $apns_data); * {@inheritdoc}
*/
public function sendMessageMultipleDevices(array $deviceTokens, Notification $notification, ?int $badge_count = NULL, array $data = [], array $apns_data = []): MulticastSendReport {
$message = $this->createMessageFromNotificationAndAddBadge($notification, $badge_count, NULL, $data, $apns_data);
$report = $this->messaging->sendMulticast($message, $deviceTokens); $report = $this->messaging->sendMulticast($message, $deviceTokens);
$log_message = 'Successful sends: '.$report->successes()->count().PHP_EOL; $log_message = 'Successful sends: ' . $report->successes()->count() . PHP_EOL;
$log_message .= 'Failed sends: '.$report->failures()->count().PHP_EOL; $log_message .= 'Failed sends: ' . $report->failures()->count() . PHP_EOL;
$this->logger->notice('Push notification results for user @uid: @log_message.', [ $this->logger->notice('Push notification results for user @uid: @log_message.', [
'@uid' => $this->account->id(), '@uid' => $this->account->id(),
'@log_message' => $log_message, '@log_message' => $log_message,
...@@ -87,7 +112,33 @@ class FirebasePhpMessagingService { ...@@ -87,7 +112,33 @@ class FirebasePhpMessagingService {
return $report; return $report;
} }
private function createMessageFromNotificationAndAddBadge($notification, ?int $badge_count = null, ?string $deviceToken = null, array $data = [], array $apns_data = [], ?string $topic = null): Message { /**
* Creates a message to be sent.
*
* @param \Kreait\Firebase\Messaging\Notification $notification
* The notification to be sent.
* @param int|null $badge_count
* The optional badge count.
* @param string|null $deviceToken
* The optional device token.
* @param array $data
* The optional message data.
* @param array $apns_data
* The optional APNS data.
* @param string|null $topic
* The optional topic.
*
* @return \Kreait\Firebase\Messaging\Message
* The message to be sent.
*/
private function createMessageFromNotificationAndAddBadge(
Notification $notification,
?int $badge_count = NULL,
?string $deviceToken = NULL,
array $data = [],
array $apns_data = [],
?string $topic = NULL,
): Message {
$message_inputs = [ $message_inputs = [
'notification' => $notification, 'notification' => $notification,
]; ];
...@@ -108,10 +159,11 @@ class FirebasePhpMessagingService { ...@@ -108,10 +159,11 @@ class FirebasePhpMessagingService {
if (!empty($apns_data)) { if (!empty($apns_data)) {
$message = $message->withApnsConfig($apns_data); $message = $message->withApnsConfig($apns_data);
} }
else if (is_int($badge_count) && $badge_count >= 0) { elseif (is_int($badge_count) && $badge_count >= 0) {
$message->withApnsConfig(ApnsConfig::new()->withBadge($badge_count)); $message->withApnsConfig(ApnsConfig::new()->withBadge($badge_count));
} }
return $message; return $message;
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment