/** * Alternative to WordPress' wp_list_pages function * * @todo refactor to decouple widget-specific logic * * @param $args mixed Array or string of WP-style arguments * @return string HTML fragment containing navigation list */ function bu_navigation_list_pages($args = '') { $defaults = array('page_id' => null, 'sections' => null, 'post_types' => array('page'), 'include_links' => true, 'echo' => 0, 'title_li' => '', 'navigate_in_section' => '', 'container_tag' => 'ul', 'container_id' => '', 'container_class' => '', 'item_tag' => 'li', 'style' => null); $r = wp_parse_args($args, $defaults); $output = ''; $section_ids = array(); // Get ancestors if a specific post is being listed if ($r['page_id']) { $all_sections = bu_navigation_load_sections($r['post_types'], $r['include_links']); $section_ids = array_keys($all_sections['sections']); $section_args = array('post_types' => $r['post_types'], 'include_links' => $r['include_links']); $r['sections'] = bu_navigation_gather_sections($r['page_id'], $section_args, $all_sections); } // Fetch post list, possibly limited to specific sections $page_args = array('sections' => $r['sections'], 'post_types' => $r['post_types'], 'include_links' => $r['include_links']); $pages = bu_navigation_get_pages($page_args); $pages_by_parent = bu_navigation_pages_by_parent($pages); $sections = !empty($r['sections']) ? $r['sections'] : array_keys($pages_by_parent); $list_attributes = ''; if ($r['container_id']) { $list_attributes .= sprintf(' id="%s"', $r['container_id']); } if ($r['container_class']) { $list_attributes .= sprintf(' class="%s"', $r['container_class']); } $html = sprintf("<%s %s>\n", $r['container_tag'], $list_attributes); if ($r['style'] == 'adaptive') { // If the "active" page isn't in the list of sections (because it has no children), add it // @todo I don't think this can ever be true based on the code in bu-navigation-adaptive-contentnav.php if ($r['page_id'] && !in_array($r['page_id'], $sections)) { array_push($sections, $r['page_id']); } if (count($sections) > 2) { $last_section = array_pop($sections); array_push($sections, $last_section); if (array_key_exists($last_section, $pages_by_parent) && is_array($pages_by_parent[$last_section]) && count($pages_by_parent[$last_section]) > 0) { // The last section has children, so it will be the "top" $sections = array_slice($sections, -2); } else { // Last section has no children, so it's parent will be the "top" $sections = array_slice($sections, -3); } } } // Default to top level pages $section = $sections[0]; // Sectional navigation requires at least two levels if ($r['navigate_in_section']) { if (isset($sections[1])) { $section = $sections[1]; } else { $section = null; } } // Loop over top section if (isset($pages_by_parent[$section]) && is_array($pages_by_parent[$section]) && count($pages_by_parent[$section]) > 0) { $sargs = array('container_tag' => $r['container_tag'], 'item_tag' => $r['item_tag'], 'depth' => 2, 'section_ids' => $section_ids); $page_position = 1; $number_siblings = count($pages_by_parent[$section]); foreach ($pages_by_parent[$section] as $page) { $child_html = bu_navigation_list_section($page->ID, $pages_by_parent, $sargs); $pargs = array('html' => $child_html, 'depth' => 1, 'position' => $page_position, 'siblings' => $number_siblings, 'item_tag' => $r['item_tag'], 'section_ids' => $section_ids); $html .= bu_navigation_format_page($page, $pargs); $page_position++; } } else { return ''; } $html .= sprintf("</%s>\n", $r['container_tag']); if ($r['echo']) { echo $html; } return $html; }
/** * Covers bu_navigation_gather_sections() */ public function test_bu_navigation_gather_sections() { $parent = $this->posts['parent']; $child = $this->posts['child']; $grandchild_one = $this->posts['grandchild_one']; $greatgrandchild = $this->posts['greatgrandchild']; /* Base Functionality */ $grandchild_expected = array(strval(0), strval($parent), strval($child), $grandchild_one); $child_expected = array(strval(0), strval($parent), $child); // Gather test results $grandchild_results = bu_navigation_gather_sections($grandchild_one, NULL, NULL); $greatgrandchild_results = bu_navigation_gather_sections($greatgrandchild, NULL, NULL); $child_results = bu_navigation_gather_sections($child, NULL, NULL); // Test base functionality $this->assertEquals($child_results, $child_expected); $this->assertEquals($grandchild_results, $grandchild_expected); /* Down Functionality (Direction) */ // Expected down results $child_down_expected = array(strval($grandchild_one), strval($child)); $parent_down_expected = $child_down_expected; array_push($parent_down_expected, strval($parent)); // Get Down results $args = array('direction' => 'down'); $child_down_results = bu_navigation_gather_sections($child, $args, NULL); $parent_down_results = bu_navigation_gather_sections($parent, $args, NULL); // Test down functionality $this->assertEquals($child_down_results, $child_down_expected); $this->assertEquals($parent_down_results, $parent_down_expected); /* Depth Functionality */ // Expected depth results $parent_depth_expected = array(strval($child), strval($parent)); // Get depth results $args = array('depth' => '1', 'direction' => 'down'); $parent_depth_results = bu_navigation_gather_sections($parent, $args, NULL); // Test depth functionality $this->assertEquals($parent_depth_results, $parent_depth_expected); /* Custom Post Type Functionality */ // Expected custom post type results $test = $this->posts['test']; $test_child = $this->posts['test_child']; $test_grandchild = $this->posts['test_grandchild']; $grandchild_posttype_expected = array(strval(0), strval($test), strval($test_child)); // Get custom post type results $args = array('post_types' => array('test')); $grandchild_posttype_results = bu_navigation_gather_sections($test_grandchild, $args, NULL); // Test custom post type functionality $this->assertEquals($grandchild_posttype_results, $grandchild_posttype_expected); /* Selective Sections Functionality */ // Section results // By giving the function only the pages from test and the seleced posts it should // yeild the same results if we had give it the post_type parameter (previous assertion) $selective_section = bu_navigation_load_sections('test'); $selective_section_results = bu_navigation_gather_sections($test_grandchild, NULL, $selective_section); // Test selective section functionality $this->assertEquals($selective_section_results, $grandchild_posttype_expected); }