(int) $node->id, 'admin_site_id' => (int) $node->admin_site_id, 'parent_id' => $node->parent_id !== null ? (int) $node->parent_id : null, 'path' => (string) $node->path, 'depth' => (int) $node->depth, 'code' => (string) $node->code, 'name' => (string) $node->name, 'status' => (int) $node->status, 'is_root' => $node->isRoot(), ]; } /** * @param iterable $nodes * @return list> */ public static function tree(iterable $nodes): array { $items = []; $byParent = []; foreach ($nodes as $node) { $row = self::item($node); $row['children'] = []; $items[(int) $node->id] = $row; $parentKey = $node->parent_id !== null ? (int) $node->parent_id : 0; $byParent[$parentKey][] = (int) $node->id; } $attach = static function (int $id) use (&$attach, &$items, $byParent): array { $node = $items[$id]; foreach ($byParent[$id] ?? [] as $childId) { $node['children'][] = $attach($childId); } return $node; }; $ids = array_keys($items); $rootIds = []; foreach ($items as $id => $row) { $parentId = $row['parent_id']; if ($parentId === null || ! in_array((int) $parentId, $ids, true)) { $rootIds[] = (int) $id; } } $roots = []; foreach ($rootIds as $rootId) { $roots[] = $attach($rootId); } return $roots; } }