Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"ext-mbstring": "*",
"ext-openssl": "*",
"guzzlehttp/guzzle": "^7.9.2",
"psr/log": "^2.0|^3.0",
"spomky-labs/base64url": "^2.0.4",
"symfony/polyfill-php83": "^1.33",
"web-token/jwt-library": "^3.4.9|^4.0.6"
Expand Down
37 changes: 26 additions & 11 deletions src/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Base64Url\Base64Url;
use Jose\Component\Core\JWK;
use Jose\Component\Core\Util\Ecc\PublicKey;
use Psr\Log\LoggerInterface;

class Utils
{
Expand Down Expand Up @@ -55,17 +56,31 @@ public static function unserializePublicKey(string $data): array
];
}

private static function logWarning(string $message, ?LoggerInterface $logger): void
{
$logger !== null
? $logger->warning($message)
: trigger_error($message, E_USER_WARNING);
}

private static function logNotice(string $message, ?LoggerInterface $logger): void
{
$logger !== null
? $logger->notice($message)
: trigger_error($message, E_USER_NOTICE);
}

/**
* Generates user warning/notice if some requirements are not met.
* Does not throw exception to allow unusual or polyfill environments.
*/
public static function checkRequirement(): void
public static function checkRequirement(?LoggerInterface $logger = null): void
{
self::checkRequirementExtension();
self::checkRequirementKeyCipherHash();
self::checkRequirementExtension($logger);
self::checkRequirementKeyCipherHash($logger);
}

public static function checkRequirementExtension(): void
public static function checkRequirementExtension(?LoggerInterface $logger = null): void
{
$requiredExtensions = [
'curl' => '[WebPush] curl extension is not loaded but is required. You can fix this in your php.ini.',
Expand All @@ -74,17 +89,17 @@ public static function checkRequirementExtension(): void
];
foreach ($requiredExtensions as $extension => $message) {
if (!extension_loaded($extension)) {
trigger_error($message, E_USER_WARNING);
self::logWarning($message, $logger);
}
}

// Check optional extensions.
if (!extension_loaded('bcmath') && !extension_loaded('gmp')) {
trigger_error('It is highly recommended to install the GMP or BCMath extension to speed up calculations. The fastest available calculator implementation will be automatically selected at runtime.', E_USER_NOTICE);
self::logNotice('It is highly recommended to install the GMP or BCMath extension to speed up calculations. The fastest available calculator implementation will be automatically selected at runtime.', $logger);
}
}

public static function checkRequirementKeyCipherHash(): void
public static function checkRequirementKeyCipherHash(?LoggerInterface $logger = null): void
{
// Print your current openssl version with: OPENSSL_VERSION_TEXT
// Check for outdated openssl without EC support.
Expand All @@ -93,11 +108,11 @@ public static function checkRequirementKeyCipherHash(): void
];
$availableCurves = openssl_get_curve_names();
if ($availableCurves === false) {
trigger_error('[WebPush] Openssl does not support curves.', E_USER_WARNING);
self::logWarning('[WebPush] Openssl does not support curves.', $logger);
} else {
foreach ($requiredCurves as $curve => $message) {
if (!in_array($curve, $availableCurves, true)) {
trigger_error($message, E_USER_WARNING);
self::logWarning($message, $logger);
}
}
}
Expand All @@ -109,7 +124,7 @@ public static function checkRequirementKeyCipherHash(): void
$availableCiphers = openssl_get_cipher_methods();
foreach ($requiredCiphers as $cipher => $message) {
if (!in_array($cipher, $availableCiphers, true)) {
trigger_error($message, E_USER_WARNING);
self::logWarning($message, $logger);
}
}

Expand All @@ -120,7 +135,7 @@ public static function checkRequirementKeyCipherHash(): void
$availableHash = hash_hmac_algos();
foreach ($requiredHash as $hash => $message) {
if (!in_array($hash, $availableHash, true)) {
trigger_error($message, E_USER_WARNING);
self::logWarning($message, $logger);
}
}
}
Expand Down
22 changes: 16 additions & 6 deletions src/WebPush.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
use GuzzleHttp\Psr7\Request;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;

class WebPush
{
protected Client $client;
protected array $auth;
protected ?LoggerInterface $logger;

/**
* @var null|array Array of array of Notifications
Expand Down Expand Up @@ -52,15 +54,23 @@ class WebPush
/**
* WebPush constructor.
*
* @param array $auth Some servers need authentication
* @param array $defaultOptions TTL, urgency, topic, batchSize, requestConcurrency
* @param int|null $timeout Timeout of POST request
* @param array $auth Some servers need authentication
* @param array $defaultOptions TTL, urgency, topic, batchSize, requestConcurrency
* @param int|null $timeout Timeout of POST request
* @param LoggerInterface|null $logger Optional PSR-3 logger; if provided, replaces trigger_error() calls
*
* @throws \ErrorException
*/
public function __construct(array $auth = [], array $defaultOptions = [], ?int $timeout = 30, array $clientOptions = [])
{
Utils::checkRequirement();
public function __construct(
array $auth = [],
array $defaultOptions = [],
?int $timeout = 30,
array $clientOptions = [],
?LoggerInterface $logger = null
) {
$this->logger = $logger;

Utils::checkRequirement($this->logger);

if (isset($auth['VAPID'])) {
$auth['VAPID'] = VAPID::validate($auth['VAPID']);
Expand Down