Skip to content
1 change: 1 addition & 0 deletions src/wp-admin/includes/meta-boxes.php
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,7 @@ function page_attributes_meta_box( $post ) {
'show_option_none' => __( '(no parent)' ),
'sort_column' => 'menu_order, post_title',
'echo' => 0,
'post_status' => array( 'publish', 'draft', 'pending', 'private' ),
);

/**
Expand Down
17 changes: 17 additions & 0 deletions src/wp-includes/post.php
Original file line number Diff line number Diff line change
Expand Up @@ -6268,6 +6268,23 @@ function get_page_children( $page_id, $pages ) {
}
}

if ( 0 === $page_id ) {
$parent_ids = array_keys( $children );
$page_ids = wp_list_pluck( $pages, 'ID' );

foreach ( $parent_ids as $parent_id ) {
if ( 0 !== $parent_id && ! in_array( $parent_id, $page_ids, true ) ) {
foreach ( $children[ $parent_id ] as $orphan ) {
$page_list[] = $orphan;
if ( isset( $children[ $orphan->ID ] ) ) {
$orphan_pages = get_page_children( $orphan->ID, $pages );
$page_list = array_merge( $page_list, $orphan_pages );
}
}
}
}
}

return $page_list;
}

Expand Down
61 changes: 61 additions & 0 deletions tests/phpunit/tests/post/wpDropdownPages.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,65 @@ public function test_wp_dropdown_pages_should_obey_class_parameter() {

$this->assertMatchesRegularExpression( '/<select[^>]+class=\'bar\'/', $found );
}

/**
* Test that published child pages remain selectable when parent is trashed.
*
* @ticket 11235
*/
public function test_child_page_available_when_parent_trashed() {
$parent_id = self::factory()->post->create(
array(
'post_type' => 'page',
'post_status' => 'publish',
)
);

$child_id = self::factory()->post->create(
array(
'post_type' => 'page',
'post_parent' => $parent_id,
'post_status' => 'publish',
)
);

wp_trash_post( $parent_id );

$output = wp_dropdown_pages( array( 'echo' => 0 ) );

$this->assertStringContainsString( 'value="' . $child_id . '"', $output, 'Published child page should remain available even when parent is trashed.' );
$this->assertStringNotContainsString( 'value="' . $parent_id . '"', $output, 'Trashed parent should not appear in dropdown.' );
}

/**
* Test that published child pages remain selectable when parent is draft or pending.
*
* @ticket 11235
*/
public function test_child_page_available_when_parent_not_published() {
$parent_id = self::factory()->post->create(
array(
'post_type' => 'page',
'post_status' => 'publish',
)
);

$child_id = self::factory()->post->create(
array(
'post_type' => 'page',
'post_parent' => $parent_id,
'post_status' => 'publish',
)
);

wp_update_post(
array(
'ID' => $parent_id,
'post_status' => 'draft',
)
);

$output = wp_dropdown_pages( array( 'echo' => 0 ) );
$this->assertStringContainsString( 'value="' . $child_id . '"', $output, 'Published child should be available when parent is draft.' );
}
}
Loading