1. Introdução ao Laravel 13.32 e o Novo Driver Nativo Mercure
O ecossistema Laravel continua expandindo suas opções para sincronização de dados em tempo real. No lançamento do Laravel 13.32, a principal novidade do framework é a inclusão de um driver de broadcasting nativo para o Mercure, desenvolvido diretamente por Kévin Dunglas no Pull Request #61474. A versão também introduziu suporte a instalação guiada do driver via comando de terminal e novas ferramentas para manipulação de arquivos e filas.
O Mercure é um protocolo aberto construído sobre Server-Sent Events (SSE) e HTTP/2 ou HTTP/3. Ele foi desenhado especificamente para publicar atualizações a partir de servidores web tradicionais em direção a navegadores e clientes móveis sem exigir conexões estatais persistentes gerenciadas pela aplicação PHP. Em vez de estabelecer conexões WebSocket bidirecionais contínuas, o cliente conecta-se ao hub Mercure usando o padrão SSE, e a aplicação Laravel simplesmente dispara requisições HTTP POST para o hub sempre que precisa entregar uma mensagem.
Em cenários onde a comunicação é predominantemente unidirecional — do backend para o navegador —, os WebSockets tradicionais introduzem complexidade desnecessária de infraestrutura, incluindo gerenciamento de estado de conexão, balanceamento de carga TCP e proxies reversos dedicados. O protocolo SSE opera sobre HTTP regular, suporta reconexão automática nativa no navegador, atravessa firewalls corporativos sem regras complexas e consome substancialmente menos recursos em arquiteturas stateless e serverless.
2. Configuração e Uso do Driver Mercure no Laravel
A integração do Mercure no Laravel 13.32 segue o mesmo padrão de abstração dos demais broadcasters suportados pelo framework. O diff inspecionado entre as tags v13.31.0 e v13.32.0 no repositório laravel/framework revela a implementação da classe Illuminate\Broadcasting\Broadcasters\MercureBroadcaster:
+namespace Illuminate\Broadcasting\Broadcasters;
+
+/**
+ * @author Kévin Dunglas <[email protected]>
+ */
+class MercureBroadcaster extends Broadcaster
+{
+ use UsePusherChannelConventions;
+
+ public function __construct(
+ protected HubInterface $hub,
+ protected int $expiration = 300,
+ protected ?ChannelEncrypter $encrypter = null,
+ protected string $topicPrefix = 'https://laravel.alt/echo/',
+ protected bool $clientEvents = true,
+ ) {
+ $this->exemptCookieFromEncryption();
+ }
A configuração do driver é declarada no arquivo config/broadcasting.php, exigindo a URL do hub Mercure e os segredos JWT para autorização e publicação:
'mercure' => [
'driver' => 'mercure',
'url' => env('MERCURE_URL', 'https://hub.example.com/.well-known/mercure'),
'secret' => env('MERCURE_JWT_SECRET'),
'jwt' => [
'publisher' => env('MERCURE_PUBLISHER_JWT'),
'subscriber' => env('MERCURE_SUBSCRIBER_JWT'),
],
],
No código da aplicação, a publicação de eventos não requer nenhuma adaptação. Qualquer evento existente que implemente a interface ShouldBroadcast funcionará imediatamente:
namespace App\Events;
use App\Models\Order;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class OrderStatusUpdated implements ShouldBroadcast
{
public function __construct(public Order $order) {}
public function broadcastOn(): array
{
return [new PrivateChannel('orders.' . $this->order->id)];
}
}
No frontend, os navegadores consomem os dados usando a API nativa EventSource do JavaScript ou clientes especializados como a biblioteca @hotwired/turbo ou clientes Mercure com suporte a autenticação por cookie:
const hubUrl = new URL('https://hub.example.com/.well-known/mercure');
hubUrl.searchParams.append('topic', 'https://laravel.alt/echo/private-orders.42');
const eventSource = new EventSource(hubUrl, { withCredentials: true });
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Atualização do pedido recebida:', data);
};
A arquitetura do Mercure desacopla o servidor de broadcast da aplicação: o hub pode rodar em uma instância independente (escrita em Go e distribuída via Caddy), enquanto o Laravel mantém seu ciclo de vida sem estado, validando o acesso por meio de JSON Web Tokens (JWT) seguros.
3. Melhorias no Filesystem: Helpers copyToDisk() e moveToDisk()
Além do broadcasting, o Laravel 13.32 adicionou facilidades na interface de armazenamento (FilesystemAdapter), submetidas no PR #61511 por Jack Bayliss e refinadas no PR #61519 por ziadoz. A mudança adiciona os métodos copyToDisk() e moveToDisk():
+ public function copyToDisk($disk, $from, $to = null)
+ {
+ $destination = $disk instanceof FilesystemContract
+ ? $disk
+ : Container::getInstance()->make(FilesystemFactory::class)->disk($disk);
+
+ if ($destination === $this && ($to ?? $from) === $from) {
+ throw new InvalidArgumentException('Cannot copy a file to the same disk and path.');
+ }
+
+ $stream = $this->readStream($from);
+
+ if (! is_resource($stream)) {
+ return false;
+ }
+
+ try {
+ return $destination->writeStream($to ?? $from, $stream);
+ } finally {
+ if (is_resource($stream)) {
+ fclose($stream);
+ }
+ }
+ }
+
+ public function moveToDisk($disk, $from, $to = null)
+ {
+ return $this->copyToDisk($disk, $from, $to) && $this->delete($from);
+ }
Anteriormente, transferir arquivos entre diferentes discos exigia abrir manualmente um stream de leitura no disco de origem e gravá-lo no disco de destino:
// Abordagem manual legada
$stream = Storage::disk('local')->readStream('invoices/invoice-123.pdf');
Storage::disk('s3')->writeStream('archives/invoice-123.pdf', $stream);
if (is_resource($stream)) {
fclose($stream);
}
Storage::disk('local')->delete('invoices/invoice-123.pdf');
// Abordagem simplificada no Laravel 13.32
Storage::disk('local')->moveToDisk('s3', 'invoices/invoice-123.pdf', 'archives/invoice-123.pdf');
Essa sintaxe declarativa previne vazamento de descritores de arquivo abertos garantindo fechamento seguro no bloco finally, e atende casos cotidianos como migração de uploads temporários locais para armazenamento definitivo em nuvem (S3/R2) ou transferências em segundo plano por jobs de backup.
4. Suporte a Enums no Gerenciamento de Filas e Outras Melhorias
Outro aprimoramento relevante no Laravel 13.32 é o suporte nativo a PHP Enums nos comandos e métodos de pausa e retomada de filas de background (PR #61464). Em aplicações estruturadas, nomes de filas costumam ser definidos através de BackedEnum:
enum QueueChannel: string
{
case Invoices = 'invoices';
case Notifications = 'notifications';
case Webhooks = 'webhooks';
}
// O gerenciador de filas agora aceita instâncias tipadas diretamente:
Queue::pause(QueueChannel::Invoices);
Queue::resume(QueueChannel::Invoices);
A aceitação direta de enums elimina strings soltas espalhadas pelo código de gerenciamento operacional, prevenindo falhas de digitação e permitindo refatorações seguras via análise estática (PHPStan/Psalm). O registro de alterações da versão 13.32 também incluiu correções de casos de borda em strings multibyte, refinamentos na resolução de atributos Eloquent e compatibilidade de contratos de sessão para futuras versões do runtime PHP.
5. Conclusão: Quando Escolher o Mercure no seu Projeto
A adição do driver Mercure nativo amplia o espectro de arquiteturas suportadas no Laravel. O Mercure é a escolha ideal para aplicações que necessitam enviar dados do servidor para os usuários com simplicidade operacional — como dashboards com métricas em tempo real, sistemas de notificação, feeds de auditoria e barras de progresso de importações. Por rodar sobre HTTP e suportar Server-Sent Events de forma nativa nos navegadores, a complexidade de proxy e manutenção de túneis persistentes é drasticamente reduzida.
Por outro lado, aplicações que exigem comunicação bidirecional de altíssima frequência e baixa latência entre clientes — como editores colaborativos com detecção de presença em tempo real ou ferramentas de chat complexas — continuam se beneficiando de soluções full-duplex via WebSockets, como o Laravel Reverb. Com o Laravel 13.32, as equipes ganham autonomia para escolher a tecnologia exata exigida pelo domínio do problema, sem abrir mão das convenções ergonômicas do framework.
Dados de fonte primária
Obtido por este site no momento da redação, diretamente da fonte primária — não de outro artigo.
CHANGELOG.md — laravel/framework v11.31.0 → v11.32.0
Diff obtido em 2026-09-25 18:52 UTC via GitHub: comparação v11.31.0...v11.32.0. Antes: v11.31.0. Depois: v11.32.0.
@@ -1,6 +1,41 @@
# Release Notes for 11.x
-## [Unreleased](https://github.com/laravel/framework/compare/v11.30.0...11.x)
+## [Unreleased](https://github.com/laravel/framework/compare/v11.31.0...11.x)
+
+## [v11.31.0](https://github.com/laravel/framework/compare/v11.30.0...v11.31.0) - 2024-11-12
+
+* [11.x] Refactor: return Command::FAILURE by [@fernandokbs](https://github.com/fernandokbs) in https://github.com/laravel/framework/pull/53354
+* Allow the Batch and Chain onQueue method to accept Backed Enums by [@onlime](https://github.com/onlime) in https://github.com/laravel/framework/pull/53359
+* Add transaction generics by [@MatusBoa](https://github.com/MatusBoa) in https://github.com/laravel/framework/pull/53357
+* Add laravel default exception blade files to view:cache by [@SamuelWei](https://github.com/SamuelWei) in https://github.com/laravel/framework/pull/53353
+* [11.x] Added `useCascadeTruncate` method for `PostgresGrammar` by [@korkoshko](https://github.com/korkoshko) in https://github.com/laravel/framework/pull/53343
+* Add Application::removeDeferredServices method by [@ollieread](https://github.com/ollieread) in https://github.com/laravel/framework/pull/53362
+* Add the ability to append and prepend middleware priority from the application builder by [@ollieread](https://github.com/ollieread) in https://github.com/laravel/framework/pull/53326
+* Fix typo in Translator code comment by [@caendesilva](https://github.com/caendesilva) in https://github.com/laravel/framework/pull/53366
+* [11.x] Handle HtmlString constructed with a null by [@sperelson](https://github.com/sperelson) in https://github.com/laravel/framework/pull/53367
+* [11.x] Add `URL::forceHttps()` to enforce HTTPS scheme for URLs by [@dasundev](https://github.com/dasundev) in https://github.com/laravel/framework/pull/53381
+* [11.x] Refactor and add remaining test cases for the DatabaseUuidFailedJobProviderTest class by [@kevinb1989](https://github.com/kevinb1989) in https://github.com/laravel/framework/pull/53408
+* [11.X] Postgres Aurora failover - DetectsLostConnections by [@vifer](https://github.com/vifer) in https://github.com/laravel/framework/pull/53404
+* `whereFullText` case consistency by [@parth391](https://github.com/parth391) in https://github.com/laravel/framework/pull/53395
+* [11.x] Add `HasFactory` trait to `make:model` generation command using `--all` options by [@adel007gh](https://github.com/adel007gh) in https://github.com/laravel/framework/pull/53391
+* Introduce support for popping items from a stackable context item by [@denjaland](https://github.com/denjaland) in https://github.com/laravel/framework/pull/53403
+* [11.x] Test Improvements by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/53414
+* [11.x] Add ability to dynamically build mailers on-demand using `Mail::build` by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/53411
+* [11.x] Refactor and add remaining test cases for the DatabaseFailedJobProviderTest class by [@kevinb1989](https://github.com/kevinb1989) in https://github.com/laravel/framework/pull/53409
+* [11.x] Fix error event listener in Vite prefetching by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/53439
+* [11.x] Ensure datetime cache durations account for script execution time by [@timacdonald](https://github.com/timacdonald) in https://github.com/laravel/framework/pull/53431
+* [11.x] Fix fluent syntax for HasManyThrough when combining HasMany followed by HasOne by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/53335
+* Correct parameter type of Collection::diffKeys() and Collection::diffKeysUsing() by [@AJenbo](https://github.com/AJenbo) in https://github.com/laravel/framework/pull/53441
+* Correct parameter type of Collection::intersectByKeys() by [@AJenbo](https://github.com/AJenbo) in https://github.com/laravel/framework/pull/53444
+* Fix schema foreign ID support for tables with non-standard primary key by [@willrowe](https://github.com/willrowe) in https://github.com/laravel/framework/pull/53442
+* [11.x] Cache token repository by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53428
+* Fix validation message when there is a parameter with escaped dot "." by [@mdmahbubhelal](https://github.com/mdmahbubhelal) in https://github.com/laravel/framework/pull/53416
+* [11.x] add optional prefix for cache key by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/53448
+* [11.x] Do not overwrite existing link header(s) in `AddLinkHeadersForPreloadedAssets` middleware by [@jnoordsij](https://github.com/jnoordsij) in https://github.com/laravel/framework/pull/53463
+* [11.x] use assertTrue and assertFalse method, instead of using assertE… by [@iamyusuf](https://github.com/iamyusuf) in https://github.com/laravel/framework/pull/53453
+* [11.x] Add `DB::build` method by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/53464
+* [11.x] Add ability to dynamically build cache repositories on-demand using `Cache::build` by [@stevebauman](https://github.com/stevebauman) in https://github.com/laravel/framework/pull/53454
+* [11.x] Skip the number of connections transacting while testing to run callbacks by [@tonysm](https://github.com/tonysm) in https://github.com/laravel/framework/pull/53377
## [v11.30.0](https://github.com/laravel/framework/compare/v11.29.0...v11.30.0) - 2024-10-30
CHANGELOG.md — laravel/framework v13.31.0 → v13.32.0
Diff obtido em 2026-09-25 18:52 UTC via GitHub: comparação v13.31.0...v13.32.0. Antes: v13.31.0. Depois: v13.32.0.
@@ -1,6 +1,48 @@
# Release Notes for 13.x
-## [Unreleased](https://github.com/laravel/framework/compare/v13.30.1...13.x)
+## [Unreleased](https://github.com/laravel/framework/compare/v13.31.0...13.x)
+
+## [v13.31.0](https://github.com/laravel/framework/compare/v13.30.1...v13.31.0) - 2026-09-08
+
+* [12.x] Ensure password hash matches stored cookie before authenticating the user by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/61386
+* [12.x] Fix TypeError in userFromRecaller() when the recaller matches no user by [@lazerg](https://github.com/lazerg) in https://github.com/laravel/framework/pull/61397
+* [13.x] Add totalSize method to Queue by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61373
+* Merge branch '12.x' into 13.x by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/61399
+* [13.x] Restore the container instance after route:cache boots a fresh application by [@lazerg](https://github.com/lazerg) in https://github.com/laravel/framework/pull/61405
+* [13.x] Include connection and queue on WorkerStopping when worker is killed by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61408
+* [13.x] Fix lazy() and lazyById() ignoring limit() and offset() by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/61402
+* [13.x] `JobInterrupted` event by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61412
+* [13.x] Make the Redis queue driver cluster-safe (`bulk()` node-less `MULTI`; `allQueueNames()` uses `KEYS`) by [@Orrison](https://github.com/Orrison) in https://github.com/laravel/framework/pull/61198
+* [13.x] feat: add chaperone support for BelongsToMany pivot models by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/61152
+* Dedupe common test fixtures by [@jasonmccreary](https://github.com/jasonmccreary) in https://github.com/laravel/framework/pull/61422
+* [13.x] feat: improve higher order proxy generic types by [@calebdw](https://github.com/calebdw) in https://github.com/laravel/framework/pull/61418
+* Apply fixes from StyleCI by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/61427
+* [13.x] Add `once` assertions to the mail and notification fakes by [@talaridisTh](https://github.com/talaridisTh) in https://github.com/laravel/framework/pull/61415
+* Let Monolog handle deprecation exceptions by [@sysdev34-wq](https://github.com/sysdev34-wq) in https://github.com/laravel/framework/pull/61414
+* [13.x] Default `memoryExceededExitCode` for Cloud by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61430
+* [13.x] Fix context not being propagated to concurrent processes by [@newtonjob](https://github.com/newtonjob) in https://github.com/laravel/framework/pull/61419
+* [13.x] Remove the unused Request import from the JSON:API resource stub by [@Bosun18](https://github.com/Bosun18) in https://github.com/laravel/framework/pull/61434
+* [13.x] Memory leak fix in Http Client by [@skr4dan](https://github.com/skr4dan) in https://github.com/laravel/framework/pull/61438
+* [13.x] Fix SelfBuilding build stack cleanup after exceptions by [@emrebalasar](https://github.com/emrebalasar) in https://github.com/laravel/framework/pull/61454
+* [13.x] defer all logic to the dedicated rule by [@browner12](https://github.com/browner12) in https://github.com/laravel/framework/pull/61445
+* Wrap the closure return type in `withFreshQueryLog()` by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/61444
+* [13.x] Fix `assertJsonMissingPath()` ignoring wildcards by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/61441
+* [13.x] Resolve the `UsePolicy` attribute from parent classes by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/61439
+* [13.x] Resolve the `UseEloquentBuilder` attribute from parent classes by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/61440
+* [13.x] Fix parameter docblocks that contradict the native signature by [@dfinchenko](https://github.com/dfinchenko) in https://github.com/laravel/framework/pull/61457
+* Bump softprops/action-gh-release from 3.0.2 to 3.0.3 in the github-actions group by [@dependabot](https://github.com/dependabot)[bot] in https://github.com/laravel/framework/pull/61468
+* [13.x] Fix RateLimited job middleware hitting limits that did not block the job by [@xurshudyan](https://github.com/xurshudyan) in https://github.com/laravel/framework/pull/61449
+* [13.x] Add `devServerUrl()` to Vite by [@ramonmalcolm10](https://github.com/ramonmalcolm10) in https://github.com/laravel/framework/pull/61465
+* [13.x] Retry phpredis commands when a connection reset surfaces as a warning by [@Orrison](https://github.com/Orrison) in https://github.com/laravel/framework/pull/61462
+* [13.x] Fix callbacks deferred from within a deferred callback by [@newtonjob](https://github.com/newtonjob) in https://github.com/laravel/framework/pull/61431
+* [13.x] Propagate command_retries to phpredis cluster connections by [@Orrison](https://github.com/Orrison) in https://github.com/laravel/framework/pull/61460
+* [13.x] Qualify soft delete column with the query's table alias by [@arunarw](https://github.com/arunarw) in https://github.com/laravel/framework/pull/61456
+* [13.x] Keep Eloquent on the direct connection during migrations by [@danielebarbaro](https://github.com/danielebarbaro) in https://github.com/laravel/framework/pull/61435
+* Apply fixes from StyleCI by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/61470
+* [13.x] Fix Class `Illuminate\Session\ArraySessionHandler` implementing `SessionHandlerInterface` is missing the `create_sid()` method which will be required in PHP 9.0 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/61469
+* Fix route url generation under certain circumstances by [@taylorotwell](https://github.com/taylorotwell) in https://github.com/laravel/framework/pull/61475
+* [13.x] Fix message ID and header persistence on ResendTransport by [@saurabhsharma2u](https://github.com/saurabhsharma2u) in https://github.com/laravel/framework/pull/61476
+* [13.x] Fix wherePivot() closure scope being ignored in pivot table operations by [@iz-ahmad](https://github.com/iz-ahmad) in https://github.com/laravel/framework/pull/61488
## [v13.30.1](https://github.com/laravel/framework/compare/v13.30.0...v13.30.1) - 2026-09-01
src/Illuminate/Broadcasting/Broadcasters/MercureBroadcaster.php — laravel/framework v13.31.0 → v13.32.0
Diff obtido em 2026-09-25 18:52 UTC via GitHub: comparação v13.31.0...v13.32.0. Antes: v13.31.0. Depois: v13.32.0.
@@ -0,0 +1,425 @@
+<?php
+
+namespace Illuminate\Broadcasting\Broadcasters;
+
+use Illuminate\Broadcasting\BroadcastException;
+use Illuminate\Broadcasting\Mercure\ChannelEncrypter;
+use Illuminate\Cookie\Middleware\EncryptCookies;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Arr;
+use JsonException;
+use RuntimeException;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\Mercure\Authorization;
+use Symfony\Component\Mercure\Exception\ExceptionInterface as MercureExceptionInterface;
+use Symfony\Component\Mercure\HubInterface;
+use Symfony\Component\Mercure\HubRegistry;
+use Symfony\Component\Mercure\Jwt\Grant;
+use Symfony\Component\Mercure\Update;
+
+/**
+ * @author Kévin Dunglas <[email protected]>
+ */
+class MercureBroadcaster extends Broadcaster
+{
+ use UsePusherChannelConventions;
+
+ /**
+ * Create a new broadcaster instance.
+ *
+ * The hub's token factory mints the subscriber cookie token and must be
+ * non-null, already carrying the static
+ * [RFC 9068](https://www.rfc-editor.org/rfc/rfc9068.html) claims; the
+ * hub's token provider mints the (longer-lived) publish token. The
+ * encrypter enables
+ * end-to-end encrypted channels: without one, using such a channel
+ * throws. Presence channels are never encrypted, as their member
+ * payloads flow through the hub's subscription API.
+ *
+ * The topic prefix namespaces every hub topic: it keeps Laravel topics
+ * from colliding with other publishers sharing the hub, and lets two
+ * applications sharing one hub (and one JWT secret) stay apart. The
+ * default is a "laravel.alt" URL: ".alt" is reserved outside the DNS
+ * ([RFC 9476](https://www.rfc-editor.org/rfc/rfc9476.html)), so the
+ * IRI is guaranteed non-resolvable and unsquattable.
+ *
+ * @param \Symfony\Component\Mercure\HubInterface $hub
+ * @param int $expiration
+ * @param \Illuminate\Broadcasting\Mercure\ChannelEncrypter|null $encrypter
+ * @param string $topicPrefix
+ * @param bool $clientEvents
+ */
+ public function __construct(
+ protected HubInterface $hub,
+ protected int $expiration = 300,
+ protected ?ChannelEncrypter $encrypter = null,
+ protected string $topicPrefix = 'https://laravel.alt/echo/',
+ protected bool $clientEvents = true,
+ ) {
+ $this->exemptCookieFromEncryption();
+ }
+
+ /**
+ * Authenticate the incoming request for a given channel.
+ *
+ * Mercure multiplexes every joined topic over one EventSource guarded by
+ * one authorization cookie, so this reads a "channel_names" array and
+ * mints a single token covering every currently-joined channel, public
+ * ones included (a hub without the "anonymous" directive rejects
+ * token-less subscribers). Authorization is per channel: a denied
+ * channel is flagged in the response and left out of the grants, so
+ * revoking one channel mid-session never takes down the others.
+ *
+ * Each authorized end-to-end encrypted channel's response entry carries
+ * the JSON Web Key decrypting its updates, the out-of-band key exchange
+ * recommended by the Mercure specification: the hub never sees the keys.
+ *
+ * Every guarded channel also gets a whisper topic the subscriber may
+ * publish to, so clients can exchange whispers directly through the hub.
+ * Confining client publish rights to those topics keeps the channel
+ * topics server-only: a whisper grant can never forge a server event.
+ *
+ * @param \Illuminate\Http\Request $request
+ * @return \Illuminate\Http\JsonResponse
+ *
+ * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+ * @throws \Illuminate\Broadcasting\BroadcastException
+ */
+ public function auth($request)
+ {
+ $channelNames = (array) $request->input('channel_names', []);
+
+ if ($channelNames === [] ||
+ count($channelNames) > 100 ||
+ $channelNames !== array_filter($channelNames, 'is_string')) {
+ throw new AccessDeniedHttpException;
+ }
+
+ $channelNames = array_unique($channelNames);
+
+ $responseChannels = [];
+ $privateTopics = [];
+ $presenceGrants = [];
+ $whisperTopics = [];
+ $user = null;
+
+ foreach ($channelNames as $channelName) {
+ $responseChannel = ['name' => $channelName];
+
+ if (! $this->isGuardedChannel($channelName)) {
+ // Public: delivery is gated by the Update's "private" flag, not by a grant here...
+ $responseChannels[] = $responseChannel;
+
+ continue;
+ }
+
+ $normalizedChannelName = $this->normalizeChannelName($channelName);
+
+ try {
+ if (! $channelUser = $this->retrieveUser($request, $normalizedChannelName)) {
Trecho truncado; o diff completo está no link de comparação.
src/Illuminate/Filesystem/FilesystemAdapter.php — laravel/framework v13.31.0 → v13.32.0
Diff obtido em 2026-09-25 18:52 UTC via GitHub: comparação v13.31.0...v13.32.0. Antes: v13.31.0. Depois: v13.32.0.
@@ -6,6 +6,7 @@
use Illuminate\Container\Container;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Contracts\Filesystem\Cloud as CloudFilesystemContract;
+use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
use Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract;
use Illuminate\Http\File;
use Illuminate\Http\Request;
@@ -667,6 +668,52 @@ public function move($from, $to)
return true;
}
+ /**
+ * Copy a file to another disk.
+ *
+ * @param string|\Illuminate\Contracts\Filesystem\Filesystem $disk
+ * @param string $from
+ * @param string|null $to
+ * @return bool
+ */
+ public function copyToDisk($disk, $from, $to = null)
+ {
+ $destination = $disk instanceof FilesystemContract
+ ? $disk
+ : Container::getInstance()->make(FilesystemFactory::class)->disk($disk);
+
+ if ($destination === $this && ($to ?? $from) === $from) {
+ throw new InvalidArgumentException('Cannot copy a file to the same disk and path.');
+ }
+
+ $stream = $this->readStream($from);
+
+ if (! is_resource($stream)) {
+ return false;
+ }
+
+ try {
+ return $destination->writeStream($to ?? $from, $stream);
+ } finally {
+ if (is_resource($stream)) {
+ fclose($stream);
+ }
+ }
+ }
+
+ /**
+ * Move a file to another disk.
+ *
+ * @param string|\Illuminate\Contracts\Filesystem\Filesystem $disk
+ * @param string $from
+ * @param string|null $to
+ * @return bool
+ */
+ public function moveToDisk($disk, $from, $to = null)
+ {
+ return $this->copyToDisk($disk, $from, $to) && $this->delete($from);
+ }
+
/**
* Get the file size of a given file.
*
CHANGELOG.md — laravel/framework v13.32.0 → v13.33.0
Diff obtido em 2026-09-25 18:52 UTC via GitHub: comparação v13.32.0...v13.33.0. Antes: v13.32.0. Depois: v13.33.0.
@@ -1,6 +1,37 @@
# Release Notes for 13.x
-## [Unreleased](https://github.com/laravel/framework/compare/v13.31.0...13.x)
+## [Unreleased](https://github.com/laravel/framework/compare/v13.32.0...13.x)
+
+## [v13.32.0](https://github.com/laravel/framework/compare/v13.31.0...v13.32.0) - 2026-09-15
+
+* [12.x] Default memoryExceededExitCode for Cloud by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61432
+* Wrap the closure return type in `withFreshQueryLog()` by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/61458
+* Wrap the autocompleter callback return type in `askWithCompletion()` by [@SanderMuller](https://github.com/SanderMuller) in https://github.com/laravel/framework/pull/61487
+* [13.x] Allow enums in queue pause/resume methods by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61464
+* [13.x] Compare lowercased index names in hasIndex by [@dwjordan](https://github.com/dwjordan) in https://github.com/laravel/framework/pull/61506
+* [13.x] Fix containsStrict() returning false when a closure matches a null value by [@bunyaminbilenkaratas](https://github.com/bunyaminbilenkaratas) in https://github.com/laravel/framework/pull/61507
+* [13.x] Pass the exception to Eloquent violation callbacks by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61504
+* [13.x] Change unused variables to named arguments by [@imanghafoori1](https://github.com/imanghafoori1) in https://github.com/laravel/framework/pull/61513
+* [13.x] Update SupportBinaryCodecTest by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61512
+* [13.x] Fix Factory::raw() with a count of zero by [@OpadaAlzaiede](https://github.com/OpadaAlzaiede) in https://github.com/laravel/framework/pull/61510
+* [13.x] Add missing implementation for `SessionHandlerInterface` for PHP 9 by [@crynobone](https://github.com/crynobone) in https://github.com/laravel/framework/pull/61517
+* [13.x] Add copyToDisk & moveToDisk to FilesystemAdapter by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61511
+* [13.x] Add a Mercure broadcast driver by [@dunglas](https://github.com/dunglas) in https://github.com/laravel/framework/pull/61474
+* [13.x] Accept filesystem instance in `copyToDisk()` and `moveToDisk()` methods by [@ziadoz](https://github.com/ziadoz) in https://github.com/laravel/framework/pull/61519
+* [13.x] Fix Str::password() returning extra characters and throwing Va… by [@bunyaminbilenkaratas](https://github.com/bunyaminbilenkaratas) in https://github.com/laravel/framework/pull/61521
+* [13.x] Fix Str::camel() not lowercasing multibyte first characters by [@rayblair06](https://github.com/rayblair06) in https://github.com/laravel/framework/pull/61545
+* [13.x] Fix collapseWithKeys() crashing when the outer collection has string keys by [@rayblair06](https://github.com/rayblair06) in https://github.com/laravel/framework/pull/61539
+* [13.x] Fix TypeError in SessionGuard::userFromRecaller() when getAuthPassword() is null by [@irabbi360](https://github.com/irabbi360) in https://github.com/laravel/framework/pull/61532
+* Strengthen mocked tests with the real thing by [@jasonmccreary](https://github.com/jasonmccreary) in https://github.com/laravel/framework/pull/61563
+* [13.x] Fix appendToPriorityList() when the referenced middleware is the first item by [@GabeSilvaDev](https://github.com/GabeSilvaDev) in https://github.com/laravel/framework/pull/61567
+* [13.x] Improve collection return types for methods that mutate by [@axlon](https://github.com/axlon) in https://github.com/laravel/framework/pull/61571
+* [13.x] Add `isManagedQueue` to CloudManager by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61568
+* [13.x] Fix Redis tagged cache not syncing tag entry expiration on touch by [@Ashot1995](https://github.com/Ashot1995) in https://github.com/laravel/framework/pull/61574
+* [13.x] Decode job payload once by [@jackbayliss](https://github.com/jackbayliss) in https://github.com/laravel/framework/pull/61526
+* [13.x] Fix `sum()` return type when the key matches a global function name by [@crishoj](https://github.com/crishoj) in https://github.com/laravel/framework/pull/61578
+* [13.x] add UnitEnum to Authorizable contract by [@hosni](https://github.com/hosni) in https://github.com/laravel/framework/pull/61589
+* [13.x] Add support for installing Mercure via broadcasting install command by [@Lea-Bar](https://github.com/Lea-Bar) in https://github.com/laravel/framework/pull/61587
+* [13.x] Preserve unchanged values when encrypting readable environment files by [@mathiasgrimm](https://github.com/mathiasgrimm) in https://github.com/laravel/framework/pull/61503
## [v13.31.0](https://github.com/laravel/framework/compare/v13.30.1...v13.31.0) - 2026-09-08