### Full Web-Push Configuration Example Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/configuration.md A comprehensive example demonstrating the setup of the Web-Push library, including logging, VAPID authentication, default options, HTTP client configuration, encryption settings, and VAPID header caching. It also shows how to use `flushPooled` for concurrent sending. ```php use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Encryption; use Monolog\Logger; use Monolog\Handlers\StreamHandler; // Set up logging $logger = new Logger('webpush'); $logger->pushHandler(new StreamHandler('php://stderr', Logger::WARNING)); // Load VAPID keys $vapid = [ 'subject' => 'mailto:push-admin@example.com', 'publicKey' => getenv('VAPID_PUBLIC_KEY'), 'privateKey' => getenv('VAPID_PRIVATE_KEY') ]; // Configure default options $defaultOptions = [ 'TTL' => 86400, // 24 hours 'urgency' => 'normal', 'topic' => 'notifications', 'batchSize' => 500, // Batches of 500 'requestConcurrency' => 50, // 50 parallel requests 'contentType' => 'application/json' ]; // HTTP client options $clientOptions = [ 'timeout' => 20, \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => false, \GuzzleHttp\RequestOptions::VERIFY => true ]; // Create WebPush $webPush = new WebPush($vapid, $defaultOptions, 20, $clientOptions, $logger); // Configure encryption (high security) $webPush->setAutomaticPadding(Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH); // Enable VAPID header caching $webPush->setReuseVAPIDHeaders(true); // Use flushPooled for better concurrency $webPush->flushPooled( callback: function($report) { if ($report->isSuccess()) { echo "✓ Delivered\n"; } else { echo "✗ Failed: " . $report->getReason() . "\n"; if ($report->isSubscriptionExpired()) { removeExpiredSubscription($report->getEndpoint()); } } }, batchSize: 500, requestConcurrency: 50 ); ``` -------------------------------- ### Example: Custom Guzzle Client Setup Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/configuration.md Demonstrates setting up the WebPush instance with custom Guzzle client options, including timeout, connection timeout, redirects, SSL verification path, and proxy. ```php $webPush = new WebPush( auth: ['VAPID' => $vapid], defaultOptions: ['TTL' => 300], timeout: 20, clientOptions: [ 'timeout' => 20, 'connect_timeout' => 10, \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => false, \GuzzleHttp\RequestOptions::VERIFY => '/path/to/cacert.pem', \GuzzleHttp\RequestOptions::PROXY => 'http://proxy.example.com:8080' ] ); ``` -------------------------------- ### Minimal Web Push Setup Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/README.md Demonstrates the most basic setup for sending a notification using the WebPush class. This minimal configuration is suitable for simple use cases where encryption is not immediately required. ```php $webPush = new WebPush(); $webPush->queueNotification($subscription); // No payload = no encryption ``` -------------------------------- ### TTL (Time-To-Live) Examples Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/configuration.md Examples demonstrating different TTL (Time-To-Live) settings for push notifications, affecting how long the push service retains the notification. ```php // Immediate delivery only (don't queue) 'TTL' => 0, // Short-lived (5 minutes) 'TTL' => 300, // Standard (24 hours) 'TTL' => 86400, // Long-lived (4 weeks, default) 'TTL' => 2419200, // Very long-lived (1 year) 'TTL' => 31536000 ``` -------------------------------- ### Full Web Push Notification Sending Example Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/MessageSentReport.md This comprehensive example illustrates the complete process of sending push notifications using the web-push-php library. It includes setting up VAPID authentication, creating subscriptions, sending notifications in a loop, and handling delivery reports, including removing expired subscriptions. ```php use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription; $webPush = new WebPush([ 'VAPID' => [ 'subject' => 'mailto:admin@example.com', 'publicKey' => '...', 'privateKey' => '...' ] ]); $subscription = Subscription::create(json_decode($_POST['subscription'], true)); $payload = json_encode(['title' => 'Hello', 'body' => 'World']); $results = []; foreach ($webPush->flush() as $report) { $results[] = [ 'endpoint' => $report->getEndpoint(), 'success' => $report->isSuccess(), 'reason' => $report->getReason(), 'expired' => $report->isSubscriptionExpired(), 'statusCode' => $report->getResponse()?->getStatusCode(), ]; if ($report->isSuccess()) { echo "[✓] Delivered to " . $report->getEndpoint() . "\n"; } else { echo "[✗] Failed to " . $report->getEndpoint() . ": " . $report->getReason() . "\n"; if ($report->isSubscriptionExpired()) { // Remove from database subscriptionRepository->delete($report->getEndpoint()); } } } // Store results for auditing db.logs.insert_many($results); ``` -------------------------------- ### Install WebPush PHP using Composer Source: https://github.com/web-push-libs/web-push-php/blob/master/README.md Use Composer to install the web-push library and its dependencies. ```bash composer require minishlink/web-push ``` -------------------------------- ### Full VAPID Workflow Example Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/VAPID.md Demonstrates the complete process of setting up and using VAPID with web-push-php, from key generation and validation to sending a notification. Keys should be generated once and stored securely. ```php use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription; use Minishlink\WebPush\VAPID; // Step 1: Generate keys once (initial setup) // $keys = VAPID::createVapidKeys(); // Store in environment: VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY // Step 2: Load and validate keys on each request $vapidConfig = VAPID::validate([ 'subject' => 'mailto:admin@example.com', 'publicKey' => getenv('VAPID_PUBLIC_KEY'), 'privateKey' => getenv('VAPID_PRIVATE_KEY') ]); // Step 3: Create WebPush with VAPID $webPush = new WebPush(['VAPID' => $vapidConfig]); // Step 4: Load subscription and send $subscription = Subscription::create( json_decode($_POST['subscription'], true) ); $payload = json_encode([ 'title' => 'Hello World', 'body' => 'Push notification' ]); $report = $webPush->sendOneNotification($subscription, $payload); if ($report->isSuccess()) { echo "Sent to " . $report->getEndpoint(); } else { echo "Error: " . $report->getReason(); } ``` -------------------------------- ### Example: Create Subscription from Direct Array Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Demonstrates creating a Subscription object directly from an associative array containing endpoint and keys. ```php // Direct array $subscription = Subscription::create([ 'endpoint' => 'https://fcm.googleapis.com/fcm/send/abc123', 'keys' => [ 'p256dh' => 'BPcMbnWQL5GOYX/5LKZXT6sLmHiMsJSiEvIFvfcDvX7IZ9qqtq68onpTPEYmyxSQNiH7UD/98AUcQ12kBoxz/0s=', 'auth' => 'CxVX6QsVToEGEcjfYPqXQw==' ] ]); ``` -------------------------------- ### Example: Create Subscription from Client-Side JSON Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Demonstrates creating a Subscription object by decoding a JSON string obtained from the client-side `PushSubscription.toJSON()` method. ```php use Minishlink\WebPush\Subscription; // From browser PushSubscription.toJSON() $clientSideJson = '{"endpoint":"https://...","keys":{"p256dh":"BPc...","auth":"abc..."}}'; $subscription = Subscription::create(json_decode($clientSideJson, true)); ``` -------------------------------- ### Custom Subscription Implementation Example Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/types.md Demonstrates how to create a custom subscription class that implements the SubscriptionInterface. This custom object can then be used with the WebPush library. ```php use Minishlink\WebPush\SubscriptionInterface; class MyCustomSubscription implements SubscriptionInterface { public function __construct( private string $endpoint, private ?string $publicKey = null, private ?string $authToken = null, private ?string $contentEncoding = 'aes128gcm' ) {} public function getEndpoint(): string { return $this->endpoint; } public function getPublicKey(): ?string { return $this->publicKey; } public function getAuthToken(): ?string { return $this->authToken; } public function getContentEncoding(): ?string { return $this->contentEncoding; } } // Use with WebPush $webPush = new WebPush(); $custom = new MyCustomSubscription('https://...', 'pubkey', 'auth', 'aes128gcm'); $webPush->queueNotification($custom, $payload); ``` -------------------------------- ### getPublicKey() Method Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/SubscriptionInterface.md Example implementation of the getPublicKey method, returning the client's P-256 public key for encryption. ```php class MySubscription implements SubscriptionInterface { public function __construct( private string $endpoint, private ?string $publicKey = null, // ... ) {} public function getPublicKey(): ?string { return $this->publicKey; } } ``` -------------------------------- ### getEndpoint() Method Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/SubscriptionInterface.md Example implementation of the getEndpoint method, returning the push service endpoint URL. ```php class MySubscription implements SubscriptionInterface { public function __construct( private string $endpoint, // ... ) {} public function getEndpoint(): string { return $this->endpoint; } } ``` -------------------------------- ### Example Usage of VAPID::validate() Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/VAPID.md Demonstrates how to use the VAPID::validate() method with different input formats (direct keys, PEM file, PEM content) and how to use the validated configuration with the WebPush class. ```php use Minishlink\WebPush\VAPID; // Method 1: Direct keys (from database/env) $vapid = VAPID::validate([ 'subject' => 'mailto:admin@example.com', 'publicKey' => getenv('VAPID_PUBLIC_KEY'), 'privateKey' => getenv('VAPID_PRIVATE_KEY') ]); // Method 2: Load from PEM file $vapid = VAPID::validate([ 'subject' => 'mailto:admin@example.com', 'pemFile' => '/secure/path/private_key.pem' ]); // Method 3: PEM string (hardcoded or from database) $pemContent = << 'https://example.com', 'pem' => $pemContent ]); // Use validated config $webPush = new WebPush(['VAPID' => $vapid]); ``` -------------------------------- ### getAuthToken() Method Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/SubscriptionInterface.md Example implementation of the getAuthToken method, returning the client's authentication secret for encryption. ```php class MySubscription implements SubscriptionInterface { public function __construct( private string $endpoint, private ?string $publicKey = null, private ?string $authToken = null, // ... ) {} public function getAuthToken(): ?string { return $this->authToken; } } ``` -------------------------------- ### Full Encryption Workflow Example Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Encryption.md Demonstrates the internal workflow of the WebPush library for handling encrypted notifications. This includes queuing notifications, automatic padding, encryption, and building the HTTP request. ```php use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription; use Minishlink\WebPush\Encryption; use Minishlink\WebPush\ContentEncoding; // 1. User queues notification $webPush = new WebPush(); $webPush->setAutomaticPadding(Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH); $subscription = Subscription::create(/* ... */); $payload = json_encode(['title' => 'Test']); $webPush->queueNotification($subscription, $payload); // 2. WebPush internally (in prepare()): // - Gets content encoding from subscription // - Calls padPayload() automatically // - Calls encrypt() automatically // - Builds HTTP request with encrypted content and headers // - Calls getContentCodingHeader() to add RFC 8291 header // 3. User sends foreach ($webPush->flush() as $report) { // Report contains encrypted payload in HTTP request } ``` -------------------------------- ### Production Web Push Setup with VAPID and Options Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/README.md Configures the WebPush class for a production environment, including VAPID authentication, default options for notifications (TTL, urgency, topic, batch size, concurrency, content type), client options, and a PSR-3 logger. Encryption is also configured. ```php $webPush = new WebPush( auth: [ 'VAPID' => [ 'subject' => 'mailto:admin@example.com', 'publicKey' => getenv('VAPID_PUBLIC_KEY'), 'privateKey' => getenv('VAPID_PRIVATE_KEY') ] ], defaultOptions: [ 'TTL' => 86400, 'urgency' => 'normal', 'topic' => 'notifications', 'batchSize' => 500, 'requestConcurrency' => 50, 'contentType' => 'application/json' ], timeout: 20, clientOptions: [ 'timeout' => 20, \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => false ], logger: $logger // PSR-3 logger ); // Configure encryption $webPush->setAutomaticPadding(Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH); $webPush->setReuseVAPIDHeaders(true); ``` -------------------------------- ### getContentEncoding() Method Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/SubscriptionInterface.md Example implementation of the getContentEncoding method, returning the content encoding standard for encryption. ```php class MySubscription implements SubscriptionInterface { public function __construct( private string $endpoint, private ?string $publicKey = null, private ?string $authToken = null, private ?string $contentEncoding = 'aes128gcm' ) {} public function getContentEncoding(): ?string { return $this->contentEncoding; } } ``` -------------------------------- ### Testing Custom Subscription Implementations Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/SubscriptionInterface.md Provides example unit tests for a custom subscription class (MySubscription) to ensure it correctly implements the SubscriptionInterface and its methods. This is crucial for verifying custom subscription logic. ```php use PHPUnit\Framework\TestCase; use Minishlink\WebPush\SubscriptionInterface; class SubscriptionTest extends TestCase { public function testImplementsInterface() { $sub = new MySubscription(...); $this->assertInstanceOf(SubscriptionInterface::class, $sub); } public function testGetEndpoint() { $sub = new MySubscription('https://example.com/...'); $this->assertEquals('https://example.com/...', $sub->getEndpoint()); } public function testGetPublicKey() { $key = 'BPc...'; $sub = new MySubscription('https://...', $key); $this->assertEquals($key, $sub->getPublicKey()); } public function testGetAuthToken() { $token = 'abc...'; $sub = new MySubscription('https://...', '...', $token); $this->assertEquals($token, $sub->getAuthToken()); } public function testGetContentEncoding() { $sub = new MySubscription('https://...', '...', '...', 'aes128gcm'); $this->assertEquals('aes128gcm', $sub->getContentEncoding()); } public function testNullEncryption() { $sub = new MySubscription('https://...'); $this->assertNull($sub->getPublicKey()); $this->assertNull($sub->getAuthToken()); $this->assertNull($sub->getContentEncoding()); } } ``` -------------------------------- ### Subject Format Examples Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/VAPID.md Illustrates the required formats for the 'subject' parameter, which identifies your application. Use 'mailto:' for email or 'https://' for a URL. Consistency is important as push services may cache this value. ```php 'subject' => 'mailto:admin@example.com' ``` ```php 'subject' => 'https://example.com' ``` -------------------------------- ### VAPID Headers for aesgcm Encoding Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/types.md Example structure for VAPID headers when using aesgcm encoding, including the Authorization and Crypto-Key. ```php [ 'Authorization' => 'WebPush eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...', 'Crypto-Key' => 'p256ecdsa=BC...(88 chars)...' ] ``` -------------------------------- ### ContentEncoding Enum Methods Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/ContentEncoding.md Demonstrates common methods available on PHP backed enums, such as getting the string value, creating an enum from a string, and listing all available cases. ```php use Minishlink\WebPush\ContentEncoding; // Get string value $encoding = ContentEncoding::aes128gcm; echo $encoding->value; // "aes128gcm" // Create from string $encoding = ContentEncoding::from('aes128gcm'); // ContentEncoding::aes128gcm $encoding = ContentEncoding::tryFrom('invalid'); // null // List all cases ContentEncoding::cases(); // [ContentEncoding::aesgcm, ContentEncoding::aes128gcm] ``` -------------------------------- ### ContentEncoding Enum Usage Examples Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/types.md Illustrates common operations with the ContentEncoding enum, such as accessing values, creating enum instances from strings, and listing all available cases. ```php ContentEncoding::aes128gcm->value // "aes128gcm" ContentEncoding::from('aes128gcm') // ContentEncoding::aes128gcm ContentEncoding::tryFrom('invalid') // null ContentEncoding::cases() // [::aesgcm, ::aes128gcm] ``` -------------------------------- ### Handle RuntimeException for Key Generation Failures Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/errors.md Catch RuntimeException when cryptographic operations like key generation or agreement fail. This can occur during VAPID key creation or encryption setup. ```php try { $keys = VAPID::createVapidKeys(); } catch (RuntimeException $e) { echo "Cannot generate keys: " . $e->getMessage(); } ``` -------------------------------- ### Get Subscription Endpoint Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Retrieve the push service endpoint URL from a Subscription object. ```php $subscription = Subscription::create($data); $endpoint = $subscription->getEndpoint(); // "https://fcm.googleapis.com/fcm/send/..." ``` -------------------------------- ### VAPID Headers for aes128gcm Encoding Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/types.md Example structure for VAPID headers when using aes128gcm encoding, where Crypto-Key is not used. ```php [ 'Authorization' => 'vapid t=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..., k=BC...(88 chars)...', 'Crypto-Key' => '' // Not used, empty or omitted ] ``` -------------------------------- ### Getting the Subscription Endpoint URL Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/MessageSentReport.md Retrieve the specific endpoint URL that was used to send the push notification from the MessageSentReport. ```php echo $report->getEndpoint(); // "https://fcm.googleapis.com/fcm/send/abc123" ``` -------------------------------- ### Initialize WebPush with Authentication and Options Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/WebPush.md Instantiate the WebPush class with authentication credentials (VAPID), default notification options, and HTTP client timeout. This sets up the client for sending push notifications. ```php use Minishlink\WebPush\WebPush; $auth = [ 'VAPID' => [ 'subject' => 'mailto:admin@example.com', 'publicKey' => '~88 chars base64url encoded', 'privateKey' => '~44 chars base64url encoded' ] ]; $defaultOptions = [ 'TTL' => 300, 'urgency' => 'normal', 'topic' => 'newMessage', 'batchSize' => 500, 'requestConcurrency' => 50, 'contentType' => 'application/json' ]; $webPush = new WebPush($auth, $defaultOptions, 20); ``` -------------------------------- ### Get Content Encoding Type Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Retrieves the content encoding type as a string. Use this for public API interactions. ```php $subscription = Subscription::create([ 'endpoint' => 'https://...', 'keys' => ['p256dh' => '...', 'auth' => '...'], 'contentEncoding' => 'aes128gcm' ]); $encoding = $subscription->getContentEncoding(); // "aes128gcm" ``` -------------------------------- ### Constructor Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/WebPush.md Initializes the WebPush class with authentication, default options, timeout, client options, and a logger. ```APIDOC ## Constructor ### Description Initializes the WebPush class with authentication, default options, timeout, client options, and a logger. ### Parameters - **auth** (array) - Required - Authentication configuration, typically with 'VAPID' key containing subject, publicKey, and privateKey. - **defaultOptions** (array) - Required - Default options for all notifications (TTL, urgency, topic, batchSize, requestConcurrency, contentType). - **timeout** (int|null) - Optional - HTTP request timeout in seconds. Defaults to 30. - **clientOptions** (array) - Required - Guzzle HTTP client options; see `\GuzzleHttp\RequestOptions`. - **logger** (LoggerInterface|null) - Optional - PSR-3 compatible logger for error reporting. Defaults to null. ### Throws - `ErrorException` - If requirements are not met (missing PHP extensions) ### Example ```php use Minishlink\WebPush\WebPush; $auth = [ 'VAPID' => [ 'subject' => 'mailto:admin@example.com', 'publicKey' => '~88 chars base64url encoded', 'privateKey' => '~44 chars base64url encoded' ] ]; $defaultOptions = [ 'TTL' => 300, 'urgency' => 'normal', 'topic' => 'newMessage', 'batchSize' => 500, 'requestConcurrency' => 50, 'contentType' => 'application/json' ]; $webPush = new WebPush($auth, $defaultOptions, 20); ``` ``` -------------------------------- ### Load and Configure VAPID Keys from Environment Variables Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/configuration.md This pattern demonstrates loading VAPID public and private keys, along with other configuration options like subject, TTL, and urgency, from environment variables. It includes error handling for missing essential variables. ```php // Load from environment $vapidPublicKey = getenv('VAPID_PUBLIC_KEY') or throw new Exception('Missing VAPID_PUBLIC_KEY'); $vapidPrivateKey = getenv('VAPID_PRIVATE_KEY') or throw new Exception('Missing VAPID_PRIVATE_KEY'); // Configure $webPush = new WebPush([ 'VAPID' => [ 'subject' => getenv('VAPID_SUBJECT') ?: 'mailto:admin@example.com', 'publicKey' => $vapidPublicKey, 'privateKey' => $vapidPrivateKey ] ]); // Or with default options $webPush->setDefaultOptions([ 'TTL' => (int)(getenv('PUSH_TTL') ?: 2419200), 'urgency' => getenv('PUSH_URGENCY') ?: 'normal' ]); ``` -------------------------------- ### Getting Request Details from a Report Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/MessageSentReport.md Retrieve the HTTP request object from a MessageSentReport to inspect details like the endpoint, headers, and payload. ```php $report = $webPush->sendOneNotification($subscription, $payload); $request = $report->getRequest(); $endpoint = $request->getUri()->__toString(); // "https://fcm.googleapis.com/fcm/send/வதற்காக" $headers = $request->getHeaders(); // ['TTL' => ['300'], 'Urgency' => ['normal'], ...] $body = $request->getBody()->getContents(); // Encrypted payload bytes ``` -------------------------------- ### Using SubscriptionInterface with WebPush Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/SubscriptionInterface.md Demonstrates how to use the WebPush class with different implementations of the SubscriptionInterface, including the built-in Subscription class and custom implementations. It shows how to queue notifications and send them. ```php use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription; $webPush = new WebPush($auth); // Use built-in Subscription class $builtIn = Subscription::create([ 'endpoint' => 'https://...', 'keys' => ['p256dh' => '...', 'auth' => '...'] ]); $webPush->queueNotification($builtIn, $payload); // Use custom implementation $custom = new CustomSubscription(...); $webPush->queueNotification($custom, $payload); // Use any implementation foreach ($subscriptions as $sub) { if ($sub instanceof SubscriptionInterface) { $webPush->queueNotification($sub, $payload); } } // Send all foreach ($webPush->flush() as $report) { // Handle results } ``` -------------------------------- ### Constructor with LoggerInterface Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/types.md Demonstrates how to accept an optional PSR-3 LoggerInterface in a constructor. This allows for flexible logging configurations. ```php use Psr\Log\LoggerInterface; public function __construct( // ... ?LoggerInterface $logger = null ) { } ``` -------------------------------- ### Instantiate WebPush with VAPID Authentication Source: https://github.com/web-push-libs/web-push-php/blob/master/README.md Demonstrates how to instantiate the WebPush class with VAPID authentication details. Supports passing keys directly, using a PEM file path, or providing PEM content. ```php [ // Recommended. 'subject' => 'mailto:me@website.com', // Must be an email beginning with mailto: or available https website address. 'publicKey' => '~88 chars', // Uncompressed public key P-256 encoded in Base64-URL. 'privateKey' => '~44 chars', // In fact the secret multiplier of the private key encoded in Base64-URL. ], 'VAPID' => [ // Alternative 1. 'subject' => 'mailto:me@website.com', // Must be an email beginning with mailto: or available https website address. 'pemFile' => 'path/to/pem', // If you have a PEM file and can link to it on your filesystem. ], 'VAPID' => [ // Alternative 2. 'subject' => 'mailto:me@website.com', // Must be an email beginning with mailto: or available https website address. 'pem' => 'pemFileContent', // If you have a PEM file and want to hardcode its content. ], ]; $webPush = new WebPush($auth); $webPush->queueNotification(...); ``` -------------------------------- ### Inspect Web Push Request and Response Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/errors.md Iterate through push reports to get detailed information about the request and response, especially for failed operations. This is useful for debugging. ```php foreach ($webPush->flush() as $report) { if (!$report->isSuccess()) { // Get full request $request = $report->getRequest(); echo "Method: " . $request->getMethod() . "\n"; echo "URL: " . $request->getUri() . "\n"; echo "Headers: " . json_encode($request->getHeaders()) . "\n"; // Get response $response = $report->getResponse(); if ($response) { echo "Status: " . $response->getStatusCode() . "\n"; echo "Body: " . $response->getBody() . "\n"; } } } ``` -------------------------------- ### Instantiate Subscription with Modern Format Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Create a Subscription object using the modern format with endpoint, public key, auth token, and content encoding. ```php use Minishlink\WebPush\Subscription; // Modern format with 'keys' array (from browser PushSubscription.toJSON()) $sub = new Subscription( 'https://fcm.googleapis.com/fcm/send/abc...', 'BPc...88_char_base64url_string...', 'abcd...24_char_base64url_string...', 'aes128gcm' ); ``` -------------------------------- ### Verify OpenSSL Features for WebPush Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/errors.md Ensure your OpenSSL installation supports the 'prime256v1' curve and 'aes-128-gcm' cipher, and that PHP supports 'sha256' HMAC. Update OpenSSL if necessary. ```bash # Check OpenSSL version and features openssl version -a openssl ecparam -list_curves | grep prime256v1 openssl enc -list | grep aes-128-gcm # Update OpenSSL if outdated ``` -------------------------------- ### Instantiate Subscription with Legacy Firefox Format Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Create a Subscription object using the legacy Firefox format with endpoint, public key, auth token, and content encoding. ```php // Old Firefox format $sub = new Subscription( 'https://updates.push.services.mozilla.com/push/abc...', 'BPc...88_char_base64url_string...', 'abcd...24_char_base64url_string...', 'aesgcm' ); ``` -------------------------------- ### create() - Static Factory Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Creates a Subscription instance from various array formats, commonly from browser `PushSubscription.toJSON()` output. ```APIDOC ## create() (Static Factory) Create a Subscription from various array formats (browser `PushSubscription.toJSON()` output). ### Parameters | Parameter | Type | Required | Description | |---|---|---|---| | associativeArray | array | yes | Array with keys: endpoint (required), and one of: keys (array with p256dh, auth) OR (publicKey, authToken), and optional contentEncoding | ### Return Type `Subscription` - New instance ### Throws - `ErrorException` - If required fields are missing ### Supported Array Formats **Modern standard format (W3C Push API):** ```php $sub = Subscription::create([ 'endpoint' => 'https://fcm.googleapis.com/fcm/send/...', 'keys' => [ 'p256dh' => 'BPc...88_chars...', 'auth' => 'abcd...24_chars...' ], 'contentEncoding' => 'aes128gcm' // optional, defaults to aesgcm ]); ``` **Legacy format (older browsers):** ```php $sub = Subscription::create([ 'endpoint' => 'https://updates.push.services.mozilla.com/push/...', 'publicKey' => 'BPc...88_chars...', 'authToken' => 'abcd...24_chars...', 'contentEncoding' => 'aesgcm' ]); ``` **Chrome GCM format (no encryption keys):** ```php $sub = Subscription::create([ 'endpoint' => 'https://fcm.googleapis.com/fcm/send/...' ]); ``` **From client-side PushSubscription directly:** ```php // Client-side: var json = pushSubscription.toJSON(); // Server-side PHP: $sub = Subscription::create(json_decode($clientJson, true)); ``` ### Example ```php use Minishlink\WebPush\Subscription; // From browser PushSubscription.toJSON() $clientSideJson = '{"endpoint":"https://...","keys":{"p256dh":"BPc...","auth":"abc..."}}'; $subscription = Subscription::create(json_decode($clientSideJson, true)); // Direct array $subscription = Subscription::create([ 'endpoint' => 'https://fcm.googleapis.com/fcm/send/abc123', 'keys' => [ 'p256dh' => 'BPcMbnWQL5GOYX/5LKZXT6sLmHiMsJSiEvIFvfcDvX7IZ9qqtq68onpTPEYmyxSQNiH7UD/98AUcQ12kBoxz/0s=', 'auth' => 'CxVX6QsVToEGEcjfYPqXQw==' ] ]); ``` ``` -------------------------------- ### Handle Invalid Content Encoding Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/errors.md Ensure the content encoding is either 'aesgcm' or 'aes128gcm'. The example shows how to catch a ValueError for incorrect encoding and how to instantiate Subscription with a valid encoding. ```php try { $sub = new Subscription( 'https://...', 'key', 'auth', 'invalid_encoding' // Wrong! ); } catch (ValueError $e) { echo "Invalid encoding: " . $e->getMessage(); } // Use valid encoding $sub = new Subscription( 'https://...', 'key', 'auth', 'aes128gcm' // Correct ); ``` -------------------------------- ### Create Subscription from Client-Side JSON Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Use the static `create` method to instantiate a Subscription by decoding client-side JSON, typically from `PushSubscription.toJSON()`. ```php // Client-side: var json = pushSubscription.toJSON(); // Server-side PHP: $sub = Subscription::create(json_decode($clientJson, true)); ``` -------------------------------- ### Create Subscription from Legacy Array Format Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Use the static `create` method to instantiate a Subscription from an associative array following a legacy format. ```php $sub = Subscription::create([ 'endpoint' => 'https://updates.push.services.mozilla.com/push/...', 'publicKey' => 'BPc...88_chars...', 'authToken' => 'abcd...24_chars...', 'contentEncoding' => 'aesgcm' ]); ``` -------------------------------- ### Get Safe String Length Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Utils.md Calculates the length of a string using multibyte-aware operations to prevent issues with different character encodings. It is used throughout the library for all length checks. ```php use Minishlink\WebPush\Utils; $len = Utils::safeStrlen('Hello'); // 5 $len = Utils::safeStrlen('你好'); // 6 (3 bytes per character) ``` -------------------------------- ### Creating and Using Subscription Objects Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/SubscriptionInterface.md Illustrates different ways to create subscription objects, including using the built-in Subscription class constructor, its factory method, and custom implementations. All these objects can be used with the WebPush class. ```php // Built-in class $sub = new Subscription('https://...', 'key', 'auth', 'aes128gcm'); // Factory $sub = Subscription::create([ 'endpoint' => 'https://...', 'keys' => ['p256dh' => '...', 'auth' => '...'] ]); // Custom implementation $sub = new MySubscription(...); // All work with WebPush $webPush->queueNotification($sub, $payload); ``` -------------------------------- ### Unserialize Public Key from Binary Data Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Utils.md Deserializes an uncompressed EC point (binary format) into X and Y coordinates. This is the inverse of serializePublicKey() and expects a 65-byte input starting with the 0x04 prefix. ```php use Minishlink\WebPush\Utils; $publicKey = hex2bin('04' . '...64_hex_chars_X...' . '...64_hex_chars_Y...'); [$x, $y] = Utils::unserializePublicKey($publicKey); // $x: 32 bytes // $y: 32 bytes // Used in VAPID::getVapidHeaders() [$x, $y] = Utils::unserializePublicKey($publicKey); $jwk = new JWK([ 'x' => Base64Url::encode($x), 'y' => Base64Url::encode($y), // ... ]); ``` -------------------------------- ### Setting Default Options Later Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/configuration.md Initialize WebPush without default options and set them later using the setDefaultOptions method. ```php $webPush = new WebPush(); $webPush->setDefaultOptions($defaultOptions); ``` -------------------------------- ### Serialize MessageSentReport to JSON Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/MessageSentReport.md This example demonstrates how to convert a MessageSentReport object into a JSON string using json_encode(). The resulting JSON includes details about the success status, expiration, reason, endpoint, and payload. ```php $report = $webPush->sendOneNotification($subscription, $payload); $json = json_encode($report); // {"success":true,"expired":false,"reason":"OK","endpoint":"https://...","payload":"..."} // Stored in database or sent to client ``` -------------------------------- ### Basic Error Handling with try-catch Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/errors.md Demonstrates a basic try-catch block to handle exceptions during notification queuing and flushing. It iterates through flush reports to check for individual notification success or failure. ```php use Minishlink\WebPush\WebPush; $webPush = new WebPush($vapid); try { $webPush->queueNotification($subscription, $payload); foreach ($webPush->flush() as $report) { if (!$report->isSuccess()) { echo "Error: " . $report->getReason() . "\n"; } } } catch (Exception $e) { echo "Exception: " . $e->getMessage(); } ``` -------------------------------- ### WebPush Constructor Options Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/types.md Default options and client options for the WebPush constructor, including TTL, urgency, topic, batch size, concurrency, content type, and VAPID authentication configuration. ```APIDOC ## WebPush Constructor Options ### Location `src/WebPush.php` ### DefaultOptions ```php [ 'TTL' => int, // Time-to-live seconds (default: 2419200 = 4 weeks) 'urgency' => ?string, // 'very-low'|'low'|'normal'|'high' (default: null) 'topic' => ?string, // Max 32 URL-safe Base64 chars (default: null) 'batchSize' => int, // Notifications per batch (default: 1000) 'requestConcurrency' => int, // Parallel requests in flushPooled (default: 100) 'contentType' => string // MIME type (default: 'application/octet-stream') ] ``` ### Auth Configuration ```php [ 'VAPID' => InputVapidConfig // See VAPID types above ] ``` ``` -------------------------------- ### Subscribe with VAPID Public Key on Client-Side Source: https://github.com/web-push-libs/web-push-php/blob/master/README.md Illustrates how to subscribe to push notifications on the client-side using the VAPID public key. Requires a `urlBase64ToUint8Array` function. ```js serviceWorkerRegistration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(vapidPublicKey) }) ``` -------------------------------- ### Send Notifications with Concurrency Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/README.md This example demonstrates sending notifications concurrently using flushPooled() with a specified batch size and request concurrency. It utilizes a callback function to process the results of each sent notification. ```php $webPush = new WebPush( auth: $auth, defaultOptions: ['batchSize' => 500, 'requestConcurrency' => 50] ); // Queue notifications for ($i = 0; $i < 10000; $i++) { $webPush->queueNotification($subscriptions[$i], $payload); } // Send with parallel requests $webPush->flushPooled( callback: function($report) { if ($report->isSuccess()) { logSuccess($report->getEndpoint()); } else { logError($report->getEndpoint(), $report->getReason()); } } ); ``` -------------------------------- ### checkRequirement() Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Utils.md Verifies that the PHP environment has all the required extensions and features for the Web Push library. It logs warnings if any essential components are missing, ensuring the library can operate correctly. ```APIDOC ## checkRequirement() ### Description Verify PHP environment has all required extensions and features. Logs warnings if missing. ### Method `static public function checkRequirement(?LoggerInterface $logger = null): void` ### Parameters #### Path Parameters - **logger** (LoggerInterface|null) - Optional - PSR-3 logger; if null, uses trigger_error() ### Warnings Generated **Required Extensions:** - curl – For HTTP requests - mbstring – For string encoding safety - openssl – For encryption and VAPID **Optional Extensions (notice-level):** - bcmath OR gmp – For performance optimization **OpenSSL Features:** - prime256v1 curve – For ECDH key agreement - aes-128-gcm cipher – For payload encryption **Hash Algorithms:** - sha256 – For HKDF and VAPID JWT signing ### Behavior - If required extension missing: Logs warning - If no hash algorithm support: Logs warning - If no bcmath/gmp: Logs notice (still works, just slower) - Does not throw exceptions (allows unusual environments) ### Example ```php use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Utils; use Psr\Log\NullLogger; // Check with logger $logger = new NullLogger(); Utils::checkRequirement($logger); // Logger will receive warning/notice messages // Called automatically in WebPush constructor: $webPush = new WebPush([], [], 30, [], $logger); // checkRequirement() is called internally ``` ``` -------------------------------- ### Retrieve Raw Response Content Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/MessageSentReport.md This snippet shows how to get the raw response body from the push service, which can be useful for debugging or understanding specific error messages. It handles cases where no response was received. ```php if (!$report->isSuccess()) { $content = $report->getResponseContent(); if ($content) { error_log("Push service response: " . $content); } } ``` -------------------------------- ### VAPID Authentication with PEM File Path Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/configuration.md Configure VAPID authentication by providing the path to a PEM-encoded private key file and a subject identifier. ```php $webPush = new WebPush([ 'VAPID' => [ 'subject' => 'mailto:my@website.com', 'pemFile' => '/path/to/private_key.pem' ] ]); ``` -------------------------------- ### Set Automatic Padding in WebPush Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/errors.md Manage automatic padding for payloads. Valid values range from 0 to 4078 bytes, with 2820 bytes recommended for compatibility. Examples show valid and invalid padding values. ```php // Valid range: 0-4078 $webPush->setAutomaticPadding(false); // 0 bytes $webPush->setAutomaticPadding(512); // 512 bytes $webPush->setAutomaticPadding(true); // 2820 bytes (default) $webPush->setAutomaticPadding(4078); // Max // Invalid $webPush->setAutomaticPadding(5000); // Too large! $webPush->setAutomaticPadding(-100); // Negative! ``` -------------------------------- ### Validate VAPID Configuration from PEM File Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/VAPID.md Validates VAPID configuration by providing the path to a PEM-encoded private key file. The subject must also be provided. ```php VAPID::validate([ 'subject' => 'mailto:admin@example.com', 'pemFile' => '/path/to/private_key.pem' ]) ``` -------------------------------- ### Generate VAPID Keys Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/VAPID.md Generates a new VAPID key pair. This method should be called once during setup, and the generated keys should be stored permanently and securely. The public key is shared with clients, while the private key must be kept secret. ```php use Minishlink\WebPush\VAPID; // Run once during setup $keys = VAPID::createVapidKeys(); // Store securely: // $keys['publicKey'] → database/env var, share with clients // $keys['privateKey'] → environment variable only, keep secret file_put_contents('/secure/path/vapid_keys.json', json_encode($keys)); ``` -------------------------------- ### Migrating Subscriptions Between Content Encodings Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/ContentEncoding.md Demonstrates creating subscriptions with both old ('aesgcm') and new ('aes128gcm') content encodings and how WebPush handles them seamlessly. Use this when migrating existing subscriptions or integrating with modern browsers. ```php use Minishlink\WebPush\Subscription; use Minishlink\WebPush\ContentEncoding; // Old subscriptions with aesgcm $oldSub = Subscription::create([ 'endpoint' => 'https://...', 'keys' => ['p256dh' => '...', 'auth' => '...'], 'contentEncoding' => 'aesgcm' ]); // New subscriptions with aes128gcm (from modern browsers) $newSub = Subscription::create([ 'endpoint' => 'https://...', 'keys' => ['p256dh' => '...', 'auth' => '...'], 'contentEncoding' => 'aes128gcm' ]); // Both work seamlessly with WebPush $webPush = new WebPush(); $webPush->queueNotification($oldSub, $payload); // aesgcm $webPush->queueNotification($newSub, $payload); // aes128gcm foreach ($webPush->flush() as $report) { // Each handled with correct encoding } ``` -------------------------------- ### Check and Enable PHP Extensions Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/errors.md Verify that required PHP extensions (curl, mbstring, openssl) are loaded. If not, enable them in your php.ini file and re-verify using the command line. ```bash # Check which extensions are loaded php -m | grep -E 'curl|mbstring|openssl' # Enable in php.ini extension=curl extension=mbstring extension=openssl # Verify php -m | grep -E 'curl|mbstring|openssl' ``` -------------------------------- ### Send Push Notification with Subscription Source: https://github.com/web-push-libs/web-push-php/blob/master/_autodocs/api-reference/Subscription.md Demonstrates how to create a Subscription object from client-side JSON data and use it with the WebPush service to queue and send a notification. Ensure the client JSON is properly decoded. ```php use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription; // Create subscription from client-side data $clientJson = $_POST['subscription']; $subscription = Subscription::create(json_decode($clientJson, true)); // Queue notification $webPush = new WebPush(); $payload = json_encode(['title' => 'Hello', 'body' => 'World']); $webPush->queueNotification($subscription, $payload); // Send foreach ($webPush->flush() as $report) { if ($report->isSuccess()) { echo "Delivered to: " . $subscription->getEndpoint(); } } ``` -------------------------------- ### Generate VAPID Keys using PHP Function Source: https://github.com/web-push-libs/web-push-php/blob/master/README.md Shows how to generate VAPID keys using the `createVapidKeys` function in PHP. The generated keys should be stored for later use. ```php var_dump(VAPID::createVapidKeys()); // store the keys afterwards ```