collect_children($root_id, $result, 0, $max_depth); return $result; } /** * Recursive helper to collect pages in order. */ private function collect_children(int $parent_id, array &$result, int $depth, int $max_depth): void { if ($depth >= $max_depth) { return; } $children = get_pages([ 'parent' => $parent_id, 'sort_column' => 'menu_order, post_title', 'sort_order' => 'ASC', 'post_status' => 'publish', ]); foreach ($children as $child) { $child->_depth = $depth; $result[] = $child; $this->collect_children($child->ID, $result, $depth + 1, $max_depth); } } /** * Get sibling pages for chapter navigation (prev/next). * * @param int $page_id Current page ID. * @return array{prev: object|null, next: object|null} */ public function get_chapter_nav(int $page_id): array { $parent_id = wp_get_post_parent_id($page_id); $siblings = get_pages([ 'parent' => $parent_id ?: 0, 'sort_column' => 'menu_order, post_title', 'sort_order' => 'ASC', 'post_status' => 'publish', ]); $current_index = -1; foreach ($siblings as $i => $sibling) { if ((int) $sibling->ID === $page_id) { $current_index = $i; break; } } $prev = $current_index > 0 ? $siblings[$current_index - 1] : null; $next = ($current_index >= 0 && $current_index < count($siblings) - 1) ? $siblings[$current_index + 1] : null; return ['prev' => $prev, 'next' => $next]; } /** * Get root-level document pages for the document navigation index. * * @param string $order Sort order: 'menu_order', 'date', 'title'. * @return array */ public function get_root_pages(string $order = 'menu_order'): array { $sort_column = 'menu_order, post_title'; if ($order === 'title') { $sort_column = 'post_title'; } elseif ($order === 'date') { $sort_column = 'post_date'; } return get_pages([ 'sort_column' => $sort_column, 'sort_order' => 'ASC', 'parent' => 0, 'hierarchical' => 0, 'post_status' => 'publish', ]); } /** * Get recently modified pages for the sidebar. * * @param int $count Number of pages to return. * @return array */ public function get_recent_pages(int $count = 8): array { return get_pages([ 'sort_column' => 'post_modified', 'sort_order' => 'DESC', 'number' => $count, 'post_status' => 'publish', ]); } /** * Build breadcrumb trail for a document page. * * @param int $page_id Current page ID. * @return array Array of {id, title, url} objects. */ public function get_breadcrumbs(int $page_id): array { $trail = []; $current = get_post($page_id); while ($current) { array_unshift($trail, [ 'id' => $current->ID, 'title' => $current->post_title, 'url' => get_permalink($current->ID), ]); $parent_id = wp_get_post_parent_id($current->ID); $current = $parent_id ? get_post($parent_id) : null; } return $trail; } /** * Search document pages by keyword. * * @param string $keyword Search keyword. * @param int $root_id Optional root page ID to scope search. * @param int $limit Max results. * @return array Array of page objects with 'url' and 'excerpt' added. */ public function search_pages(string $keyword, int $root_id = 0, int $limit = 20): array { $args = [ 'post_type' => 'page', 'post_status' => 'publish', 's' => $keyword, 'posts_per_page' => $limit, 'orderby' => 'relevance', ]; if ($root_id > 0) { $tree_ids = [$root_id]; $this->collect_children($root_id, $tree_ids, 0, 4); $ids = array_map(static function ($item) { return is_object($item) ? $item->ID : (int) $item; }, $tree_ids); $ids[] = $root_id; $args['post__in'] = array_unique($ids); } $query = new WP_Query($args); $results = []; foreach ($query->posts as $post) { $results[] = [ 'id' => $post->ID, 'title' => $post->post_title, 'url' => get_permalink($post->ID), 'excerpt' => wp_trim_words(wp_strip_all_tags($post->post_content), 30), 'modified' => $post->post_modified, 'parent' => (int) $post->post_parent, ]; } wp_reset_postdata(); return $results; } /** * Check whether a given page belongs to the docs mode. * * @param int $page_id Page ID. * @return bool */ public function is_docs_page(int $page_id): bool { if (!class_exists('AKSRT_Settings')) { return false; } $settings = AKSRT_Settings::get_docs_mode_settings(); if (empty($settings['enabled'])) { return false; } $template = get_page_template_slug($page_id); return in_array($template, [ 'templates/pages/page-documentnav.php', 'templates/pages/page-special.php', ], true); } }