Tu problema se soluciona con recursividad, es decir, tienes una función que obtiene únicamente los elementos sin categoria_madre, que serían los elementos de raíz.
Luego, vas iterando dicha lista llamando nuevamente a la función pero ahora usando su propio ID como categoria_madre de sus propios elementos, etc.
Al ser una solución recursiva debería ser muy simple construir algo así:
Código PHP:
Ver originalfunction getTree($parent) {
$out = [];
$sql = "SELECT * FROM table WHERE parent_id = $parent";
while ($row = each_obj($items)) {
$out[$row->id] = [
'title' => $row->title,
'childs' => getTree($row->id)
];
}
return $out;
}
$all = getTree(0);
Esa es la idea, no es código real pero ejemplifica perfectamente lo que debes hacer.
Suerte con lo tuyo.