P4A 3 framework: db_navigator helper per estrarre un ramo da un dbtree

by: spadamar15-01-2009

Esempio di db_navigatorQuesto helper deriva naturalmente dalla funzione descritta nel precedente post.P4A mette a disposizione un widget chiamato P4A_DB_Navigator che si basa su archivi di tipo albero a liste di adiacenza e fornisce un output grafico della lista dei nodi, con un buon grado di interattività. Esiste, per esempio, un metodo che si chiama getPath() che restituisce in un array, il percorso dalla root al nodo fornito in input attraverso la chiave primaria. Purtroppo però, non esiste nessun metodo per estrarre l’insieme di nodi figli da un certo nodo parentale, così ho pensato di adottare la funzione presentata nel precedente post.

I parametri di input sono:

  • $navigator – l’oggetto da cui discende (implicito)
  • $id – l’identificativo del nodo da cui partire
  • $table – il nome della tabella che rappresenta l’albero
  • $pk – il nome della chiave primaria
  • $recursor – il nome del campo che identifica il nodo parentale

Ecco il codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// File: P4A_db_navigator_getBranch.php
<?php
function P4A_db_navigator_getBranch ($navigator, $params)
{
  list($id, $table, $pk, $recursor) = $params;
  $arr = p4a_db::singleton()->getAll("SELECT * FROM $table");
  $pksArr = array();
  foreach ($arr as $rec) {
    $pksArr[$rec[$pk]]=$rec[$recursor];
  }
  $branchIds = array($id);
  $i=0;
  while ($i<count($branchIds)) {
    $newKeys = array_keys($pksArr,$branchIds[$i]);
    if (!empty($newKeys)) {
      foreach ($newKeys as $newKey){
        array_push($branchIds, $newKey);
      }
    }
    ++$i;
  }
  $res = array();
  foreach ($arr as $child) {
    if (in_array($child[$pk], $branchIds)) {
      $res[] = $child;
    }
  }
  return $res;
}
?>

Come esempio ho costruito una semplicissima maschera nella quale, ogni volta che viene selezionato un nodo, viene mostrato un messaggio con l’array dei nodi figli.

Ecco il codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class dbtree extends P4A_Base_Mask
{
  public function __construct()
  {
    parent::__construct();
    $this->setTitle('Test dbTree');
    //Source
    $this->build("p4a_db_source","dbtree")
      ->setTable("tree")
      ->setPk("id")
      ->load()
      ->firstRow();
    $this->setSource($this->dbtree);
    // db_navigator
    $this->build("p4a_db_navigator","navigator")
      ->setSource($this->dbtree)
      ->setRecursor("parent_id")
      ->setDescription("nome")
      ->setStyleProperty("height","85%")
      ->setStyleProperty("overflow","auto")
      ->collapse(true);
    // Display
    $this->display("sidebar_left",$this->navigator);
    // Intercept action afterMoveRow
    $this->intercept($this->dbtree,"afterMoveRow","showBranch");
  }
	public function showBranch()
  {
    $idCommessa = $this->dbtree->fields->id->getNewValue();
    $arr = $this->navigator->getBranch ($idCommessa, "tree", "id", "parent_id");
    $this->info(print_r($arr,true));
  }
}

L’esempio completo è scaricabile qui.

Conclusioni

Lancio l’idea di mettere questa funzione fra i metodi del P4A_db_navigator, sempre che non esca fuori qualche dannato baco :-).

Riferimenti ed approfondimenti: