Uma implementação de conjunto aninhado de múltiplas raízes para usuários DBAL.
Esta biblioteca fornece classes de gravação, leitura e inspeção para conjuntos aninhados com vários nós raiz por tabela. Baseando-se apenas na Doutrina DBAL.
Ao contrário de outras soluções, esta biblioteca tem limites claros e deixa o design do software por sua conta.
Use o compositor para instalar a biblioteca
> composer require shopware/dbal-nested-set
Você sempre precisa de uma configuração que defina os nomes básicos das colunas da sua implementação:
use Shopware DbalNestedSet NestedSetConfig ;
$ config = new NestedSetConfig (
' id ' , // Primary key column name
' left ' , // left column name
' right ' , // right column name
' level ' // level column name
);
Então você pode usar NestedSetFactory
para criar as diferentes classes da biblioteca.
use Shopware DbalNestedSet NestedSetFactory ;
use Doctrine DBAL Connection ;
$ writer = NestedSetFactory:: createWriter ( $ dbalConnection , $ config );
Você pode querer criar um esquema normalizado para tabelas de conjuntos aninhados; isso pode ser feito por meio de NestedSetTableFactory
. Ele criará o DDL base para uma árvore com índices. Então, se você quiser adicionar uma árvore simples com uma coluna de nome e um ID de incremento automático, ela ficará assim:
$ 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 ());
É claro que isso é opcional e pode ser realizado através de qualquer ferramenta de configuração de esquema.
A biblioteca fornece uma classe NestedSetWriter
que contém todas as operações de inserção, movimentação e atualização. Todas as operações devem lembrar DoctrineDBALConnection::insert()
e DoctrineDBALConnection::update()
e requerem apenas dados simples.
Como exemplo, você pode usar isso para criar uma árvore
$ 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 ' ]);
E então use o escritor para mover os nós
$ writer -> moveAsNextSibling ( ' tree ' , ' root_id ' , 4 , 7 );
Você pode querer recuperar informações sobre diferentes nós. Isso pode ser feito através do NestedSetTableNodeInspector
.
$ inspector = NestedSetFactory:: createTableNodeInspector ( $ connection , $ config );
$ inspector -> isLeaf ( ' tree ' , ' root_id ' , 9 ); // true | false
$ inspector -> isAncestor ( ' tree ' , ' root_id ' , 1 , 2 ) // true | false
O NestedSetQueryFactory
ajuda a recuperar um conjunto de nós da árvore. Como a biblioteca não tem conceito de entidades, ela apenas preparará construtores de consultas prontos para adicionar seleções, junções e outras condições.
$ queryFactory = NestedSetFactory:: createQueryFactory ( $ connection , $ config );
$ data = $ queryFactory
-> createChildrenQueryBuilder ( ' tree ' , ' t ' , ' root_id ' , 2 )
-> select ( ' * ' )
-> execute ()
-> fetchAll ();
Se você quiser desenvolver localmente você pode ter que configurar o acesso ao banco de dados através de um pequeno shell script:
#! /usr/bin/env bash
export DB_USER= ' foo '
export DB_PASSWORD= ' bar '
export DB_HOST= ' baz '
export DB_NAME= ' dbal_nested_set '
bin/phpunit