1. Go to this page and download the library: Download betocampoy/champs-frontend library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
use BetoCampoy\Champs\Frontend\Response\AjaxFormResponse;
$response = AjaxFormResponse::make()
->messageSuccess('Registro salvo com sucesso!')
->domPatchHtml(['target' => '#lista'], $html)
->redirect('/registros');
header('Content-Type: application/json');
echo $response->toJson();
class FcmClient
{
public function __construct(
private readonly HttpClientInterface $httpClient,
string $serviceAccountPath, // caminho para o JSON baixado
) { ... }
// Envia para um token específico
// $options: ['icon' => URL, 'link' => URL, 'data' => []]
public function sendToToken(string $token, string $title, string $body, array $options = []): bool { ... }
// Envia para todos os dispositivos de um usuário (remove tokens inválidos automaticamente)
public function sendToUser(User $user, string $title, string $body, PushSubscriptionRepository $repo, array $options = []): int { ... }
}
// Um token por linha, vinculado ao usuário logado no momento do registro.
// Quando um usuário diferente loga no mesmo browser, o token é transferido (upsert por token único).
class PushSubscription
{
private User $user;
private string $token; // único — um browser = um token
private ?string $userAgent;
private DateTimeImmutable $createdAt;
private DateTimeImmutable $lastSeenAt;
}
// POST /push/registrar
public function register(Request $request, PushSubscriptionRepository $repo): JsonResponse
{
$data = json_decode($request->getContent(), true) ?? [];
if ($token = $data['token'] ?? null) {
$repo->upsert($this->getUser(), $token, $data['userAgent'] ?? null);
}
return new JsonResponse(['ok' => true]);
}
$fcm->sendToUser($user, 'Tarefa pendente', 'Você tem 3 tarefas para hoje.', $repo, [
'icon' => 'https://meusite.com/images/icon-192.png',
'link' => 'https://meusite.com/agenda/todos',
]);