Une implémentation d'ensembles imbriqués multi-racines pour les utilisateurs de DBAL.
Cette bibliothèque vous fournit des classes d'écriture, de lecture et d'inspection pour les ensembles imbriqués avec plusieurs nœuds racine par table. S'appuyant uniquement sur la Doctrine DBAL.
Contrairement à d'autres solutions, cette bibliothèque a des limites claires et vous laisse la conception du logiciel.
Utilisez composer pour installer la bibliothèque
> composer require shopware/dbal-nested-set
Vous avez toujours besoin d'une configuration qui définit les noms de colonnes de base de votre implémentation :
use Shopware DbalNestedSet NestedSetConfig ;
$ config = new NestedSetConfig (
' id ' , // Primary key column name
' left ' , // left column name
' right ' , // right column name
' level ' // level column name
);
Ensuite, vous pouvez utiliser le NestedSetFactory
pour créer les différentes classes de la bibliothèque.
use Shopware DbalNestedSet NestedSetFactory ;
use Doctrine DBAL Connection ;
$ writer = NestedSetFactory:: createWriter ( $ dbalConnection , $ config );
Vous souhaiterez peut-être créer un schéma normalisé pour les tables d'ensembles imbriquées, cela peut être réalisé via NestedSetTableFactory
. Il créera le DDL de base pour un arbre avec des index. Donc, si vous souhaitez ajouter un arbre simple avec une colonne de nom et un identifiant à incrémentation automatique, cela ressemblera à ceci :
$ tableFactory = NestedSetFactory:: createTableFactory ( $ connection , $ config );
$ schema = new Doctrine DBAL Schema Schema ();
$ table = $ tableFactory -> createTable (
$ schema ,
' tree ' , // table name
' root_id ' // nested set root id
);
$ table -> addColumn ( ' id ' , ' integer ' , [ ' unsigned ' => true , ' autoincrement ' => true ]);
$ table -> addColumn ( ' name ' , ' string ' , [ ' length ' => 255 ]);
$ table -> setPrimaryKey ([ ' id ' ]);
$ addSql = $ schema -> toSql ( $ connection -> getDatabasePlatform ());
Bien entendu, cela est facultatif et peut être réalisé via n’importe quel outil de configuration de schéma.
La bibliothèque fournit une classe NestedSetWriter
qui contient toutes les opérations d'insertion, de déplacement et de mise à jour. Toutes les opérations doivent rappeler DoctrineDBALConnection::insert()
et DoctrineDBALConnection::update()
et nécessiter simplement des données simples.
A titre d'exemple, vous pouvez utiliser ceci pour créer un arbre
$ writer = NestedSetFactory:: createWriter ( $ dbalConnection , $ config );
// create a Root node
$ writer -> insertRoot ( ' tree ' , ' root_id ' , 100 , [ ' name ' => ' Clothing ' ]);
// create subnodes
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 1 , [ ' name ' => ' Men ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 2 , [ ' name ' => ' Women ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 2 , [ ' name ' => ' Suits ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 3 , [ ' name ' => ' Dresses ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 5 , [ ' name ' => ' Skirts ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 6 , [ ' name ' => ' Blouses ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 4 , [ ' name ' => ' Jackets ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 4 , [ ' name ' => ' Slacks ' ]);
$ writer -> insertAsFirstChild ( ' tree ' , ' root_id ' , 5 , [ ' name ' => ' Evening Gowns ' ]);
$ writer -> insertAsNextSibling ( ' tree ' , ' root_id ' , 10 , [ ' name ' => ' Sun Dresses ' ]);
Et puis utilisez l'écrivain pour déplacer les nœuds
$ writer -> moveAsNextSibling ( ' tree ' , ' root_id ' , 4 , 7 );
Vous souhaiterez peut-être récupérer des informations sur différents nœuds. Cela peut être fait via NestedSetTableNodeInspector
.
$ inspector = NestedSetFactory:: createTableNodeInspector ( $ connection , $ config );
$ inspector -> isLeaf ( ' tree ' , ' root_id ' , 9 ); // true | false
$ inspector -> isAncestor ( ' tree ' , ' root_id ' , 1 , 2 ) // true | false
NestedSetQueryFactory
permet de récupérer un ensemble de nœuds de l'arborescence. Étant donné que la bibliothèque n'a aucun concept d'entités, elle préparera uniquement des générateurs de requêtes prêts à ajouter des sélections, des jointures et d'autres conditions.
$ queryFactory = NestedSetFactory:: createQueryFactory ( $ connection , $ config );
$ data = $ queryFactory
-> createChildrenQueryBuilder ( ' tree ' , ' t ' , ' root_id ' , 2 )
-> select ( ' * ' )
-> execute ()
-> fetchAll ();
Si vous souhaitez développer localement, vous devrez peut-être configurer l'accès à la base de données via un petit script shell :
#! /usr/bin/env bash
export DB_USER= ' foo '
export DB_PASSWORD= ' bar '
export DB_HOST= ' baz '
export DB_NAME= ' dbal_nested_set '
bin/phpunit