query(' SELECT * FROM tags WHERE kind = {string:album} ORDER BY id_parent, {raw:order}', [ 'order' => $order . ($direction == 'up' ? ' ASC' : ' DESC'), 'album' => 'Album', ]); $albums_by_parent = []; while ($row = $db->fetch_assoc($res)) { if (!isset($albums_by_parent[$row['id_parent']])) $albums_by_parent[$row['id_parent']] = []; $albums_by_parent[$row['id_parent']][] = $row + ['children' => []]; } $albums = self::getChildrenRecursively(0, 0, $albums_by_parent); $rows = self::flattenChildrenRecursively($albums); return $rows; } private static function getChildrenRecursively($id_parent, $level, &$albums_by_parent) { $children = []; if (!isset($albums_by_parent[$id_parent])) return $children; foreach ($albums_by_parent[$id_parent] as $child) { if (isset($albums_by_parent[$child['id_tag']])) $child['children'] = self::getChildrenRecursively($child['id_tag'], $level + 1, $albums_by_parent); $child['tag'] = ($level ? str_repeat('—', $level * 2) . ' ' : '') . $child['tag']; $children[] = $child; } return $children; } private static function flattenChildrenRecursively($albums) { if (empty($albums)) return []; $rows = []; foreach ($albums as $album) { $rows[] = array_intersect_key($album, array_flip(['id_tag', 'tag', 'slug', 'count'])); if (!empty($album['children'])) { $children = self::flattenChildrenRecursively($album['children']); foreach ($children as $child) $rows[] = array_intersect_key($child, array_flip(['id_tag', 'tag', 'slug', 'count'])); } } return $rows; } }