Skip to content

Commit 8ee4646

Browse files
committed
Drop authorization/discovery methods from helper
1 parent 4f990f4 commit 8ee4646

File tree

3 files changed

+144
-666
lines changed

3 files changed

+144
-666
lines changed

README.md

Lines changed: 40 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,20 @@ Push real-time updates to clients using the Mercure protocol.
1919
- [Running a Mercure Hub](#running-a-mercure-hub)
2020
- [Configuration](#configuration)
2121
- [Basic Usage](#basic-usage)
22+
- [Choosing Your Authorization Strategy](#choosing-your-authorization-strategy)
2223
- [Publishing Updates](#publishing-updates)
2324
- [Publishing JSON Data](#publishing-json-data)
2425
- [Publishing Rendered Views](#publishing-rendered-views)
2526
- [Subscribing to Updates](#subscribing-to-updates)
2627
- [Authorization](#authorization)
2728
- [Publishing Private Updates](#publishing-private-updates)
2829
- [Setting Authorization Cookies](#setting-authorization-cookies)
29-
- [Using the Component (Recommended)](#using-the-component-recommended)
30-
- [Using the View Helper](#using-the-view-helper)
31-
- [Using the Facade (Alternative)](#using-the-facade-alternative)
30+
- [Using the Component](#using-the-component)
31+
- [Authorization Builder Pattern](#authorization-builder-pattern)
32+
- [Setting Default Topics](#setting-default-topics)
33+
- [Using the Facade classes](#using-the-facade-classes)
3234
- [Mercure Discovery](#mercure-discovery)
33-
- [Using the View Helper](#using-the-view-helper)
34-
- [Using the Facade](#using-the-facade)
35+
- [Using the Component](#using-the-component-1)
3536
- [Using Middleware](#using-middleware)
3637
- [Advanced Configuration](#advanced-configuration)
3738
- [JWT Token Strategies](#jwt-token-strategies)
@@ -169,11 +170,11 @@ For a complete list of available environment variables, see the plugin's `config
169170
170171
The plugin provides multiple integration points depending on your use case:
171172
172-
- **Templates**: Use the `MercureHelper` for the easiest, self-contained integration (handles authorization and URLs)
173-
- **Controllers**: Use the `MercureComponent` for centralized authorization and separation of concerns (recommended for testability)
174-
- **Services/Commands**: Use the `Publisher` facade for publishing updates
175-
- **Manual Control**: Use the `Authorization` facade when you need direct response manipulation
173+
- **Controllers**: Use the `MercureComponent` to centrally manage both authorization and subscriptions as topics
174+
- **Templates**: Use the `MercureHelper` to generate Mercure topic URLs for EventSource subscriptions in your views and templates.
175+
- **Services & Manual Control**: Use the `Publisher` facade to publish updates and the `Authorization` facade for direct response manipulation when you need lower-level control (e.g., outside controllers/views, such as in background jobs or custom middleware).
176176
177+
> [!TIP]
177178
> **Note:** Facades (`Publisher`, `Authorization`) can be used in any context where a CakePHP component or helper does not fit, such as in queue jobs, commands, models, or other non-HTTP or background processing code. This makes them ideal for use outside of controllers and views.
178179
179180
### Choosing Your Authorization Strategy
@@ -182,15 +183,10 @@ Pick the approach that best fits your workflow:
182183
183184
| Scenario | Recommended Approach | Method to Use |
184185
|----------|---------------------|---------------|
185-
| **Authorize in controller, display URL in template** | `MercureComponent` + `url()` | `$this->Mercure->authorize()` in controller, `$this->Mercure->url($topics)` in template |
186-
| **Authorize directly in template** | `MercureHelper::url()` with `subscribe` | `$this->Mercure->url($topics, $subscribe)` |
187-
| **Public topics (no authorization)** | `url()` | `$this->Mercure->url($topics)` |
186+
| **Authorize in controller, display URL in template** | `MercureComponent` + `MercureHelper` | `$this->Mercure->authorize()` in controller, `$this->Mercure->url($topics)` in template |
187+
| **Public topics (no authorization)** | `MercureHelper` | `$this->Mercure->url($topics)` |
188188
| **Manual response control** | `Authorization` facade | `Authorization::setCookie($response, $subscribe)` |
189189
190-
> [!TIP]
191-
> * **Easiest:** Use `MercureHelper::url($topics, $subscribe)` directly in templates for quick setup.
192-
> * **Best Practice:** For larger applications, handle authorization in controllers using `MercureComponent`, then use `url($topics)` in templates. This keeps authorization logic centralized and testable.
193-
194190
### Publishing Updates
195191
196192
Use the `Publisher` facade to send updates to the Mercure hub:
@@ -405,11 +401,6 @@ Publisher::publish($update);
405401
406402
The plugin provides a View Helper to generate Mercure URLs in your templates.
407403
408-
> [!IMPORTANT]
409-
> **Authorization Consideration:** When using the `MercureHelper`, understand the difference:
410-
> - `$this->Mercure->url($topics)` - Gets URL **without authorization** (when `$subscribe` is omitted)
411-
> - `$this->Mercure->url($topics, $subscribe)` - Gets URL **and sets authorization cookie** (when `$subscribe` is provided)
412-
413404
First, load the helper in your controller or `AppView`:
414405
415406
```php
@@ -476,8 +467,6 @@ eventSource.onmessage = (event) => {
476467
};
477468
```
478469
479-
The special topic `*` matches all updates (use with caution in production).
480-
481470
## Authorization
482471
483472
### Publishing Private Updates
@@ -498,9 +487,9 @@ Private updates are only delivered to subscribers with valid JWT tokens containi
498487
499488
### Setting Authorization Cookies
500489
501-
#### Using the Component (Recommended for Separation of Concerns)
490+
#### Using the Component
502491
503-
For centralized, testable authorization logic, use the `MercureComponent` in controllers. Topics added via the component are automatically available in your views:
492+
For centralized authorization logic, use the `MercureComponent` in controllers. Topics added via the component are automatically available in your views:
504493
505494
```php
506495
class BooksController extends AppController
@@ -548,7 +537,7 @@ class BooksController extends AppController
548537
}
549538
```
550539
551-
The component provides separation of concerns (authorization in controller, URLs in template) and is fully testable. You can also enable automatic discovery headers:
540+
The component provides separation of concerns (authorization in controller, URLs in template). You can also enable automatic discovery headers:
552541
553542
```php
554543
// In AppController
@@ -587,40 +576,6 @@ $this->Mercure
587576
->discover();
588577
```
589578
590-
#### Using the View Helper (Easiest)
591-
592-
For the simplest, self-contained approach, use the `MercureHelper::url()` method with the `subscribe` parameter. This **automatically handles both authorization and URL generation** in one call:
593-
594-
```php
595-
// In your template
596-
<script>
597-
// url() with subscribe parameter SETS AUTHORIZATION COOKIE
598-
const url = '<?= $this->Mercure->url(
599-
topics: ['https://example.com/books/<?= $book->id ?>'],
600-
subscribe: ['https://example.com/books/<?= $book->id ?>']
601-
) ?>';
602-
603-
const eventSource = new EventSource(url, {
604-
withCredentials: true
605-
});
606-
607-
eventSource.onmessage = (event) => {
608-
console.log('Private update:', event.data);
609-
};
610-
</script>
611-
```
612-
613-
> [!NOTE]
614-
> **Separation of Concerns:** The `url()` method **only sets authorization when the `$subscribe` parameter is provided**. If you're already handling authorization in your controller (via `MercureComponent`), simply omit the `$subscribe` parameter:
615-
>
616-
> ```php
617-
> // Authorization already set in controller
618-
> $this->Mercure->authorize(['/books/123']);
619-
>
620-
> // In template: just get the URL (no duplicate authorization)
621-
> const url = '<?= $this->Mercure->url(['/books/123']) ?>';
622-
> ```
623-
624579
#### Setting Default Topics
625580
626581
You can configure default topics that will be automatically merged with any topics you provide to `url()`. This is useful when you want certain topics (like notifications or global alerts) to be included in every subscription:
@@ -641,6 +596,25 @@ public function initialize(): void
641596
}
642597
```
643598
599+
> [!NOTE]
600+
> You can also set default topics using the `MercureComponent` in your controller:
601+
>
602+
> ```php
603+
> // In your controller
604+
> public function initialize(): void
605+
> {
606+
> parent::initialize();
607+
> $this->loadComponent('Mercure.Mercure', [
608+
> 'defaultTopics' => [
609+
> 'https://example.com/notifications',
610+
> 'https://example.com/alerts'
611+
> ]
612+
> ]);
613+
> }
614+
> ```
615+
>
616+
> This will make the default topics available to the helper in your views as well.
617+
644618
Now every call to `url()` will automatically include these default topics:
645619
646620
```php
@@ -660,7 +634,7 @@ const url = '<?= $this->Mercure->url(['/books/123']) ?>';
660634
// Result includes: /notifications, /alerts, /user/{id}/messages, /books/456, /comments/789, AND /books/123
661635
```
662636

663-
#### Using the Facade (Alternative)
637+
#### Using the Facade classes
664638

665639
For more control or when not using controllers, you can use the `Authorization` facade directly:
666640

@@ -688,13 +662,13 @@ The cookie must be set before establishing the EventSource connection. The Mercu
688662

689663
The Mercure protocol supports automatic hub discovery via HTTP Link headers. This allows clients to discover the hub URL without hardcoding it, making your application more flexible and following the Mercure specification.
690664

691-
### Using the View Helper
665+
### Using the Component
692666

693-
Add the discovery header in your templates or layouts:
667+
Add the discovery header from your controller using the `MercureComponent`:
694668

695669
```php
696-
// In your layout or template
697-
<?php $this->Mercure->discover(); ?>
670+
// In your controller action
671+
$this->Mercure->discover();
698672
```
699673

700674
This adds a `Link` header to the response:
@@ -718,26 +692,9 @@ fetch('/api/resource')
718692
});
719693
```
720694

721-
### Using the Facade
722-
723-
You can also add the discovery header manually from controllers:
724-
725-
```php
726-
use Mercure\Authorization;
727-
728-
public function index()
729-
{
730-
$response = Authorization::addDiscoveryHeader($this->response);
731-
732-
// Your controller logic here
733-
734-
return $response;
735-
}
736-
```
737-
738695
### Using Middleware
739696

740-
For automatic discovery headers on all responses, add the middleware to your application:
697+
This is an alternative approach to add the discovery header automatically to all responses by using middleware:
741698

742699
```php
743700
// In src/Application.php
@@ -1095,11 +1052,6 @@ Static facade for direct authorization management (alternative to component).
10951052
| `url(array\|string\|null $topics, array $subscribe, array $additionalClaims)` | `string` | Get hub URL **and optionally authorize** (only sets cookie when `$subscribe` is provided). Merges with default topics if configured. |
10961053
| `addTopic(string $topic)` | `$this` | Add a single topic to default topics (fluent interface) |
10971054
| `addTopics(array $topics)` | `$this` | Add multiple topics to default topics (fluent interface) |
1098-
| `authorize(array $subscribe, array $additionalClaims)` | `void` | Set authorization cookie explicitly |
1099-
| `clearAuthorization()` | `void` | Clear authorization cookie |
1100-
| `discover()` | `void` | Add Mercure discovery Link header |
1101-
| `getCookieName()` | `string` | Get the cookie name |
1102-
| `getConfig(string $key, mixed $default)` | `mixed` | Get helper configuration (e.g., `getConfig('defaultTopics', [])`) |
11031055

11041056
**Configuration Options:**
11051057

0 commit comments

Comments
 (0)