Aller au contenu

Installation

phil/edit-lock-bundle

Prérequis

PHP 8.5 ou plus récent, Symfony 8.2 avec FrameworkBundle et sa protection CSRF (symfony/security-csrf), DoctrineBundle avec DBAL 4 et ORM 3, un service clock (symfony/clock), et phil/ujo. phil/ujo-bundle est recommandé : les blocs enregistrés sont alors vérifiés avec les types de blocs propres à l'application. Pour pousser la présence et les enregistrements, MercureBundle et un hub Mercure. Dans le navigateur, Stimulus 3 servi par symfony/stimulus-bundle et AssetMapper, ainsi que l'éditeur de blocs de phil/block-editor-bundle.

Activer le bundle

composer require phil/edit-lock-bundle
// config/bundles.php
return [
    // …
    Phil\EditLockBundle\PhilEditLockBundle::class => ['all' => true],
];

Les tables

Le bundle associe Phil\EditLockBundle\Domain\Model\Lease et LeasedResource pour Doctrine, sous la forme des tables phil_edit_lease et phil_edit_lease_resource : créez-les avec les migrations de l'application.

bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate
ColonneTypeRôle
resourceVARCHAR(255), clé primaireLa ressource, telle que l'application la nomme
partVARCHAR(64), clé primaireL'identifiant du bloc ; vide pour la ressource entière
holder_id, holder_nameVARCHAR(255)Qui le détient, et le nom que voient les autres
acquired_at, expires_atDATETIME, UTCDepuis quand et jusqu'à quand ; expires_at est indexée
versionINTEGERAugmentée de un à chaque modification, pour la comparaison et échange

phil_edit_lease_resource contient une ligne par ressource ayant déjà fait l'objet d'un bail, la ligne que verrouille chaque revendication (concurrence) :

ColonneTypeRôle
resourceVARCHAR(255), clé primaireLa ressource, telle que l'application la nomme
claimsINTEGERLe nombre de revendications exécutées sur elle

Les services de l'application

Les points de terminaison ne répondent qu'une fois que l'application a dit qui écrit et ce que chacun peut modifier :

# config/packages/phil_edit_lock.yaml
phil_edit_lock:
    holder_provider: App\Collaboration\CurrentWriter
    policy: App\Collaboration\WritersPolicy
use Phil\EditLockBundle\Application\HolderProvider;
use Phil\EditLockBundle\Domain\ValueObject\Holder;
use Symfony\Bundle\SecurityBundle\Security;

final readonly class CurrentWriter implements HolderProvider
{
    public function __construct(private Security $security) {}

    public function holder(): ?Holder
    {
        $user = $this->security->getUser();

        return null === $user ? null : Holder::of($user->getUserIdentifier(), $user->getUserIdentifier());
    }
}

La politique est décrite dans baux, le magasin de blocs dans blocs.

Les routes

# config/routes/phil_edit_lock.yaml
phil_edit_lock:
    resource: '@PhilEditLockBundle/config/routes.php'
    prefix: /_edit-lock

Placez le préfixe derrière le pare-feu de l'application. Les routes sont énumérées dans points de terminaison. Le bundle ajoute le jeton phil_edit_lock aux csrf_protection.stateless_token_ids de FrameworkBundle, ce qui active framework.csrf_protection : laissez-la active. Avec csrf_protection: false, le conteneur s'arrête sur une LogicException qui l'indique.

Mercure

Lorsque MercureBundle est enregistré, le bundle publie vers son hub par défaut. Les mises à jour sont privées : le navigateur de chaque rédacteur a besoin du droit de s'abonner au sujet de la ressource, que l'application accorde comme l'explique MercureBundle, par exemple avec son témoin d'autorisation :

$authorization->setCookie($request, [$config['topic']]); // the topics this writer may subscribe to

Mercure présente les sujets, les messages et les options.

Le contrôleur et la feuille de style

Avec AssetMapper, le bundle associe son contrôleur sous @phil/edit-lock-bundle et sa feuille de style sous phil-edit-lock. Activez le contrôleur dans assets/controllers.json :

{
    "controllers": {
        "@phil/edit-lock-bundle": {
            "collaboration": { "enabled": true, "fetch": "eager" }
        }
    }
}
<link rel="stylesheet" href="{{ asset('phil-edit-lock/edit-lock.css') }}">

JavaScript montre le balisage et la configuration.