WebBlocks Appointments

Exigences

Version du package documentée : 0.12.2. WebBlocks CMS ^1.73.0 ; PHP >=8.3.

A Plugin WebBlocks CMS qui permet à un site de prendre des réservations sur son propre domaine, au lieu de relier les visiteurs à un service de planification tiers.

Installer

Créez l'artefact, puis installez-le via System → Plugins dans l'administrateur CMS en utilisant le flux de téléchargement ZIP normal.

composer plugin:build

L'artefact et son SHA-256 atterrissent sous build/. Installation des plugins désactivée ; activez le plugin explicitement à partir de l'écran de détail du plugin après l'avoir examiné.

Congrès

Tout ce que possède le plugin est doté d'un espace de noms par son handle, conformément aux règles de convention du package de plugin CMS :

handle              webblocks-appointments
settings namespace  webblocks_appointments
database prefix     webblocks_appointments_
admin routes        /webadmin/plugins/webblocks-appointments
public routes       /plugins/webblocks-appointments
route names         webblocks.plugins.webblocks_appointments.*
permissions         webblocks-appointments.view, .manage, .settings

Le formulaire de réservation

Ajoutez le bloc Appointment Form à une page. Le choix d'un service ou d'un jour récupère les heures disponibles sans recharger la page complète. Avec JavaScript désactivé, le formulaire GET rendu par le serveur reste disponible. Chaque réservation est soumise au serveur, qui revérifie la disponibilité.

Le titre, l'intro et l'étiquette de soumission peuvent être traduits par placement de bloc. Seule la copie du bloc est par bloc. Les services, le personnel et les heures d'ouverture s'appliquent à l'ensemble du site, car en les dupliquant par bloc, deux pages de réservation finissent par être discrètement en désaccord sur les heures d'ouverture.

Deux protections à connaître, car aucune n'est visible dans le balisage :

  • Les créneaux soumis sont dérivés et ne sont pas fiables. Le booker applique les conflits mais pas les règles qui décident de ce qui aurait dû être proposé : heures d'ouverture, délai de livraison, horizon. Sans cette nouvelle vérification, un message contrefait pourrait réserver 03h00 un dimanche fermé, car rien à ce sujet n'entre en conflit avec un rendez-vous existant.
  • source_url n'est honoré qu'en tant que chemin d'accès au même site. Une URL absolue ferait du formulaire une redirection ouverte.

Notifications

Lorsqu'une réservation arrive, l'entreprise reçoit une annonce et le visiteur reçoit une confirmation portant le rendez-vous sous forme de pièce jointe .ics - ce qui le place dans son propre calendrier sans compte, sans OAuth et sans service externe. La copie professionnelle définit le client comme réponse, de sorte qu'une réservation peut recevoir une réponse en y répondant ; l'adresse De reste l'expéditeur configuré, car l'y placer le visiteur échoue SPF.

Trois règles valent la peine d'être connues :

  • La notification se produit après la validation de la réservation, jamais à l'intérieur de la transaction. Un envoi qui lance ne doit pas annuler un créneau dont le visiteur a déjà été informé qu'il était le sien.
  • Les deux côtés sont tentés et enregistrés indépendamment. Un destinataire professionnel mal saisi ne doit pas supprimer la confirmation du visiteur, et un statut combiné ferait en sorte que l'écran d'administration se trouve exactement dans le cas où un opérateur en a besoin pour être honnête.
  • sent signifie que le transport l'a accepté, pas qu'il est arrivé. Les expéditeurs log, array et null sont signalés comme non configuré plutôt que comme envoyés, car les signaler comme envoyés est un mensonge qu'un opérateur ne peut pas voir.

Les détails des échecs stockés sont nettoyés : les chaînes de connexion et les secrets étiquetés sont expurgés et le message est masqué, car il est affiché aux opérateurs et une exception SMTP brute contient régulièrement des informations d'identification.

Le destinataire professionnel est résolu à partir du paramètre du plugin, puis de l'adresse de contact du site, puis de l'expéditeur configuré.

Rappels

Reminders sont envoyés par une commande Artisan, pas par une file d'attente - le noyau du CMS ne fournit aucune tâche en file d'attente, et l'introduction d'une dépendance de file d'attente est une décision fondamentale que ce plugin n'a aucune prise commerciale. Ajoutez-le au cron de l'hôte:

php artisan webblocks-appointments:dispatch-reminders

Toutes les quelques minutes suffisent. Chaque rendez-vous est considéré une seule fois : le résultat est enregistré quel qu'il soit, donc un run ne coûte rien quand rien n'est dû, et une adresse inaccessible n'est pas retentée à chaque tick. --dry-run rapporte ce qui sortirait. Le lead est par site et zéro désactive les rappels.

Annulation du visiteur

Les e-mails de confirmation et de rappel comportent un lien d'annulation. Il n'y a ni compte ni connexion : le cancel_token du rendez-vous est l'identifiant, qui est la seule conception réalisable dans un CMS sans système d'utilisateur public.

Trois règles assurent la sécurité et l'honnêteté :

  • GET affiche uniquement une page de confirmation ; DELETE annule. Les clients de messagerie, analyseurs de liens et systèmes de sécurité d’entreprise suivent les liens sans demande de l’utilisateur. Une annulation par GET permettrait aux filtres antispam d’annuler des réservations.
  • Un jeton inconnu et un rendez-vous inexistant apparaissent identiques. Les distinguer permettrait de tester les jetons devinés.
  • Un rendez-vous déjà commencé ne peut pas être annulé ici. Le permettre transformerait après coup une absence en annulation.

Lorsqu'un visiteur annule, l'entreprise est informée et cancelled_by enregistre qu'il s'agissait du visiteur plutôt que d'un opérateur. Si cette notification échoue, le visiteur ne la verra jamais : son annulation est déjà validée et le résultat est toujours enregistré pour l'opérateur.

Heure et exactitude

ALes instants des rendez-vous sont stockés en UTC. Les heures d'ouverture et leurs exceptions datées sont stockées sous forme d'horloge murale locale, car « nous ouvrons à 09h00 » doit signifier 09h00 des deux côtés d'un passage à l'heure d'été. L'horloge du site provient de Site::resolvedTimezone(), jamais de config('app.timezone').

Le générateur de machines à sous suit l'heure de l'horloge murale locale afin que les machines à sous atterrissent sur les marques attendues par le visiteur. Deux cas de transition en découlent, et tous deux sont délibérés :

  • Printemps en avant. Les heures d'horloge murale à l'intérieur de l'espace n'existent pas et ne sont pas proposées.
  • Retour en arrière. Les heures de l'horloge murale dans l'heure répétée existent deux fois ; le générateur sélectionne l'instant le plus tôt. La valeur par défaut de PHP est la plus récente, il s'agit donc d'un choix explicite plutôt que d'un comportement hérité.

La double réservation est évitée de trois manières : une transaction avec une lecture de chevauchement de verrouillage (le véritable garde, et le seul qui comprend les tampons et les durées différentes), un index unique (resource_id, slot_lock) comme filet de sécurité de base de données qui permet toujours de réserver à nouveau un emplacement annulé, et la traduction de la violation d'intégrité qui en résulte en une réponse d'emplacement indisponible plutôt qu'en 500.

Écrans opérateur

Appointments affiche un jour à la fois, dans la propre horloge du site, avec changements d'état et saisie manuelle. Services, Staff & Rooms et Opening Hours définissent ce qui peut être réservé et quand. Appointment settings contient les règles de réservation, et elles sont par site — deux sites dans une installation n'ont pas besoin de s'entendre sur le délai ou le mode de confirmation.

A Le service ou la ressource qui a déjà des rendez-vous est désactivé plutôt que supprimé, de sorte que les réservations passées conservent leur historique sans qu'aucune nouvelle ne puisse être effectuée. La saisie manuelle passe par le même agent de réservation que le formulaire public, elle ne peut donc pas effectuer de double réservation, mais elle ignore délibérément la nouvelle vérification de la disponibilité, car un opérateur réservant en dehors des heures d'ouverture prend une décision et n'échappe pas à une règle.

et vérifications de l'état

L'API du jeton au porteur expose les services, le personnel et les chambres, la disponibilité hebdomadaire, les exceptions datées, les paramètres et les rendez-vous en lecture seule sous /webadmin/api/plugins/webblocks-appointments. Découvrez les points de terminaison activés et les fonctionnalités requises via la découverte de l'API CMS et le schéma OpenAPI.

Plugin Vérifie la configuration de la base de données, les services et ressources actifs, les affectations de services, les heures d'ouverture, les destinataires des notifications, le courrier sortant et la planification des rappels.