Skip to content

Commit e32a382

Browse files
authored
Merge pull request #1899 from abdedarghal111/tarea3782
Tarea3782
2 parents fdb5512 + 5f78c06 commit e32a382

File tree

2 files changed

+118
-5
lines changed

2 files changed

+118
-5
lines changed

Core/Controller/ListProducto.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ protected function createViewProducto(string $viewName = 'ListProducto'): void
106106
->addFilterCheckbox('nostock', 'no-stock', 'nostock')
107107
->addFilterCheckbox('ventasinstock', 'allow-sale-without-stock', 'ventasinstock')
108108
->addFilterCheckbox('secompra', 'for-purchase', 'secompra')
109-
->addFilterCheckbox('sevende', 'for-sale', 'sevende');
109+
->addFilterCheckbox('sevende', 'for-sale', 'sevende')
110+
->addFilterTree('descendientede', 'descendant-of', 'codfamilia', 'familias', 'madre', 'codfamilia', 'descripcion');
110111
}
111112

112113
protected function createViewVariante(string $viewName = 'ListVariante'): void

Core/Lib/ListFilter/TreeFilter.php

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,22 @@
2929
*
3030
* @author Jose Antonio Cuello Principal <yopli2000@gmail.com>
3131
*/
32-
class TreeFilter extends AutocompleteFilter
32+
class TreeFilter extends SelectFilter
3333
{
3434
/** @var string */
35-
public string $fieldparent;
35+
public $fieldcode;
36+
37+
/** @var string */
38+
public $fieldparent;
39+
40+
/** @var string */
41+
public $fieldtitle;
42+
43+
/** @var string */
44+
public $table;
45+
46+
/** @var array */
47+
public $where;
3648

3749
/**
3850
* @param string $key
@@ -46,9 +58,13 @@ class TreeFilter extends AutocompleteFilter
4658
*/
4759
public function __construct(string $key, string $field, string $label, string $table, string $fieldparent, string $fieldcode = '', string $fieldtitle = '', array $where = [])
4860
{
49-
parent::__construct($key, $field, $label, $table, $fieldcode, $fieldtitle, $where);
50-
61+
$this->table = $table;
5162
$this->fieldparent = $fieldparent;
63+
$this->fieldcode = empty($fieldcode) ? $field : $fieldcode;
64+
$this->fieldtitle = empty($fieldtitle) ? $this->fieldcode : $fieldtitle;
65+
$this->where = $where;
66+
67+
parent::__construct($key, $field, $label, $this->loadValues());
5268
}
5369

5470
/**
@@ -95,4 +111,100 @@ private function getIds(): array
95111
}
96112
return $result;
97113
}
114+
115+
private function loadValues(): array
116+
{
117+
// obtener todos los elementos (cod, titulo, codPadre)
118+
$dataBase = new DataBase();
119+
$sql = "SELECT " . $this->fieldcode . ", " . $this->fieldtitle . ", " . $this->fieldparent . " FROM " . $this->table;
120+
121+
// aplicar where
122+
if (!empty($this->where)) {
123+
if (isset($this->where[0]) && $this->where[0] instanceof DataBaseWhere) {
124+
$sql .= DataBaseWhere::getSQLWhere($this->where);
125+
} else {
126+
$sql .= ' WHERE ' . implode(' AND ', $this->where);
127+
}
128+
}
129+
$sql .= " ORDER BY " . $this->fieldtitle;
130+
131+
// realizar consulta, construir y "maquillar" el árbol
132+
$rows = $dataBase->select($sql);
133+
$tree = $this->buildTree($rows);
134+
return $this->flattenTree($tree);
135+
}
136+
137+
/**
138+
* obtiene los elementos en formato [[cod = x, titulo = x, codPadre = x]...] y los devuelve
139+
* en un array de [codPadre = [codHijo...], ...] en donde codHijo es [cod = x, titulo = x, codPadre = x]
140+
* y el elemento padre de todos está dentro de la clave 'ROOT'
141+
*/
142+
private function buildTree(array $elements): array
143+
{
144+
// crear tabla con solo clave id, valor true
145+
$ids = [];
146+
foreach ($elements as $element) {
147+
$ids[$element[$this->fieldcode]] = true;
148+
}
149+
150+
// agrupar en una tabla codPadre = [codHijo...] con cada elemento
151+
$grouped = [];
152+
foreach ($elements as $element) {
153+
$pid = $element[$this->fieldparent];
154+
if (empty($pid) || !isset($ids[$pid])) {
155+
$pid = 'ROOT';
156+
}
157+
$grouped[$pid][] = $element;
158+
}
159+
160+
return $this->buildTreeRecursive($grouped, 'ROOT');
161+
}
162+
163+
/**
164+
* Recibe un array de [codPadre = [codHijo...], ...] en donde codHijo es [cod = x, titulo = x, codPadre = x]
165+
* y el argumento del id del padre o rama a construir.
166+
*
167+
* Hace una llamada recursiva a la función y construye un array en forma de arbol,
168+
* crea una rama y hace una llamada recursiva a las siguientes ramas.
169+
*
170+
* Devuelve un array en forma de arbol al final, con children = [[cod = x, titulo = x, codPadre = x, children = [elementosHijos...]]] donde
171+
* elementosHijos es otro [[cod = x, titulo = x, codPadre = x, children = [elementosHijos...]]].
172+
*/
173+
private function buildTreeRecursive(array &$grouped, $parentId): array
174+
{
175+
$branch = [];
176+
if (isset($grouped[$parentId])) {
177+
foreach ($grouped[$parentId] as $element) {
178+
$children = $this->buildTreeRecursive($grouped, $element[$this->fieldcode]);
179+
if ($children) {
180+
$element['children'] = $children;
181+
}
182+
$branch[] = $element;
183+
}
184+
}
185+
return $branch;
186+
}
187+
188+
/**
189+
* Recibe un array recursivo de elementos $tree = [elemento1, elemento2, elemento3...] donde
190+
* cada elemento tiene a su vez un $elemento['children'] = $tree con sus hijos.
191+
*
192+
* Lo formatea para una salida más intuitiva
193+
*/
194+
private function flattenTree(array $tree, int $level = 0): array
195+
{
196+
$result = [];
197+
foreach ($tree as $node) {
198+
$prefix = str_repeat('&nbsp;&nbsp;', $level);
199+
$result[] = [
200+
'code' => $node[$this->fieldcode],
201+
// si es el nivel superior entonces no mostrar espacio y bolita
202+
'description' => ($level !== 0 ? $prefix . '&bull;&nbsp;' : '') . htmlspecialchars($node[$this->fieldtitle])
203+
];
204+
if (isset($node['children'])) {
205+
$result = array_merge($result, $this->flattenTree($node['children'], $level + 1));
206+
}
207+
}
208+
return $result;
209+
}
98210
}

0 commit comments

Comments
 (0)