PHP Moving MySql Tree Node
Pergunta
Estou tendo problemas para tentar mover sub nós ou nós pais para cima ou para baixo ... não tão bom em matemática.
CREATE TABLE IF NOT EXISTS `pages` ( `page-id` mediumint(8) unsigned
Não nulo auto_incrent,
page-left
mediant (8) não assinado, não nulo,
page-right
smallint (8) não assinado, não nulo,page-title
texto não nulo,
page-content
texto não nulo,
page-time
int (11) não assinado não nulo,page-slug
texto não nulo,
page-template
texto não nulo,
page-parent
mediant (8) não assinado, não nulo,page-type
texto não nulo, chave primária (page-id
)) MOTOR = MYISAM CHARSET PADRÃO = LATIN1;INSIRA DENTRO DE
pages
(page-id
,page-left
,page-right
,page-title
,page-content
,page-time
,page-slug
,page-template
,page-parent
,page-type
) Valores (17, 1, 6, '1', '', 0, 'Parent', '', 0, ''), (18, 2, 5, '2', ', 0,' sub ' , '', 17, ''), (19, 3, 4, '3', '', 0, 'sub-sub-sub', '', 18, ''), (20, 7, 8, '5 ',' ', 0,' teste ',' ', 0' '');
Como exemplo, como eu moveria o teste acima do pai e diria que mova o sub para baixo abaixo do sub-sub, tocando com os IDs de página-esquerda/direita? O código não é necessário, apenas ajuda com o conceito SQL ou matemática, ajudaria -me a entender como movê -lo melhor ...
Solução
Então, basicamente, você deseja converter uma lista de adjacência em um conjunto aninhado? Atualize primeiro sua lista de adjacência (por exemplo, atualize os valores Page_Parent para os valores corretos para sua nova árvore) e, em seguida, execute a conversão abaixo.
Usando PHP (código básico, não testado):
class Tree
{
private $count = 0;
private $data = array();
/**
* Rebuild nested set
*
* @param $rawData array Raw tree data
*/
public function rebuild($rawData)
{
$this->data = $rawData;
$this->count = 1;
$this->traverse(0);
}
private function traverse($id)
{
$lft = $this->count;
$this->count++;
if (isset($this->data[$id])) {
$kid = $this->data[$id];
if ($kid) {
foreach ($kid as $c) {
$this->traverse($c);
}
}
}
$rgt = $this->count;
$this->count++;
// TODO: Update left and right values to $lft & $rgt in your DB for page_id $id
...
}
}
Quando você chama isso, o $ RAWData deve conter uma matriz de IDs, indexada pelo pai-ID, você pode criá-lo (com base na estrutura da sua tabela) da seguinte maneira ($ db deve conter um objeto de conexão PDO ativo):
$sql = 'SELECT page_id, page_parent FROM pages ORDER BY page_parent';
$stmt = $db->prepare($sql);
$rawData = array();
$stmt->execute();
while ($row = $stmt->fetch()) {
$parent = $row['page_parent'];
$child = $row['page_id'];
if (!array_key_exists($parent, $rawData)) {
$rawData[$parent] = array();
}
$rawData[$parent][] = $child;
}
Para fazer a conversão, você precisaria de algo como:
$tree = new Tree();
$tree->rebuild($rawData);
Então, basicamente, você cria uma matriz que contém todos os nós em sua árvore indexada pelo pai que será percorrido de maneira recursiva para determinar os valores esquerdo e direito corretos por nó.
BTW, você pode fazer isso no SQL simples (depois de adaptar os nomes da tabela/coluna):http://bytes.com/topic/mysql/answers/638123-regenerate-nested-set-using-parent_id-structure