Skip to content

Commit 90bd081

Browse files
Merge pull request #224 from JLG-WOCFR-DEV/codex/add-post-type-filter-to-blc_links_list_table
Add post type filter to broken links list
2 parents 55a5a5f + 3126da9 commit 90bd081

File tree

4 files changed

+170
-2
lines changed

4 files changed

+170
-2
lines changed

liens-morts-detector-jlg/includes/blc-admin-pages.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,37 @@ function blc_dashboard_links_page() {
225225
<?php if ($broken_links_count === 0): ?>
226226
<p><?php esc_html_e('✅ Aucun lien mort trouvé. Bravo !', 'liens-morts-detector-jlg'); ?></p>
227227
<?php else: ?>
228-
<form method="post">
229-
<?php $list_table->views(); $list_table->display(); ?>
228+
<form method="get">
229+
<?php
230+
$current_get_params = [];
231+
if (!empty($_GET) && is_array($_GET)) {
232+
$current_get_params = $_GET;
233+
}
234+
235+
foreach ($current_get_params as $key => $value) {
236+
if (in_array($key, ['s', 'post_type', 'paged'], true)) {
237+
continue;
238+
}
239+
240+
if (is_scalar($value)) {
241+
printf(
242+
'<input type="hidden" name="%1$s" value="%2$s" />',
243+
esc_attr($key),
244+
esc_attr((string) $value)
245+
);
246+
}
247+
}
248+
249+
if (isset($_REQUEST['page']) && (!isset($current_get_params['page']) || !is_scalar($current_get_params['page']))) {
250+
printf(
251+
'<input type="hidden" name="page" value="%s" />',
252+
esc_attr((string) $_REQUEST['page'])
253+
);
254+
}
255+
256+
$list_table->views();
257+
$list_table->display();
258+
?>
230259
</form>
231260
<?php endif; ?>
232261
</div>

liens-morts-detector-jlg/includes/class-blc-links-list-table.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,64 @@ protected function extra_tablenav($which) {
5757
return;
5858
}
5959

60+
$available_post_types = [];
61+
$post_types = function_exists('get_post_types') ? get_post_types(['public' => true]) : [];
62+
if (is_array($post_types)) {
63+
foreach ($post_types as $post_type) {
64+
if (is_string($post_type) && $post_type !== '') {
65+
$available_post_types[] = $post_type;
66+
}
67+
}
68+
}
69+
70+
$selected_post_type = '';
71+
if (isset($_GET['post_type'])) {
72+
$candidate = sanitize_key(wp_unslash($_GET['post_type']));
73+
if ($candidate !== '') {
74+
$selected_post_type = $candidate;
75+
}
76+
}
77+
78+
if (!empty($available_post_types)) {
79+
echo '<div class="alignleft actions">';
80+
echo '<label class="screen-reader-text" for="blc-post-type-filter">' . esc_html__('Filtrer par type de contenu', 'liens-morts-detector-jlg') . '</label>';
81+
82+
$select = '<select name="post_type" id="blc-post-type-filter" aria-label="' . esc_attr__('Filtrer par type de contenu', 'liens-morts-detector-jlg') . '">';
83+
$select .= '<option value="">' . esc_html__('Tous les types de contenu', 'liens-morts-detector-jlg') . '</option>';
84+
85+
foreach ($available_post_types as $post_type) {
86+
$label = $post_type;
87+
if (function_exists('get_post_type_object')) {
88+
$post_type_object = get_post_type_object($post_type);
89+
if (is_object($post_type_object)) {
90+
if (isset($post_type_object->labels) && is_object($post_type_object->labels) && !empty($post_type_object->labels->singular_name)) {
91+
$label = (string) $post_type_object->labels->singular_name;
92+
} elseif (!empty($post_type_object->label)) {
93+
$label = (string) $post_type_object->label;
94+
}
95+
}
96+
}
97+
98+
$is_selected = ($selected_post_type === $post_type) ? ' selected="selected"' : '';
99+
$select .= sprintf(
100+
'<option value="%1$s"%3$s>%2$s</option>',
101+
esc_attr($post_type),
102+
esc_html($label),
103+
$is_selected
104+
);
105+
}
106+
107+
$select .= '</select>';
108+
echo $select; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
109+
110+
printf(
111+
'<input type="submit" class="button" value="%s" />',
112+
esc_attr__('Filtrer', 'liens-morts-detector-jlg')
113+
);
114+
115+
echo '</div>';
116+
}
117+
60118
echo $this->get_search_box(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
61119
}
62120

@@ -349,6 +407,24 @@ public function prepare_items($data = null, $total_items_override = null) {
349407
$current_page = max(1, (int) $this->get_pagenum());
350408
$search_term = $this->get_search_term();
351409

410+
$available_post_types = [];
411+
$post_types = function_exists('get_post_types') ? get_post_types(['public' => true]) : [];
412+
if (is_array($post_types)) {
413+
foreach ($post_types as $post_type) {
414+
if (is_string($post_type) && $post_type !== '') {
415+
$available_post_types[] = $post_type;
416+
}
417+
}
418+
}
419+
420+
$selected_post_type = '';
421+
if (isset($_GET['post_type'])) {
422+
$candidate = sanitize_key(wp_unslash($_GET['post_type']));
423+
if ($candidate !== '') {
424+
$selected_post_type = $candidate;
425+
}
426+
}
427+
352428
if (is_array($data)) {
353429
$total_items = ($total_items_override !== null) ? (int) $total_items_override : count($data);
354430
$this->set_pagination_args(['total_items' => $total_items, 'per_page' => $per_page]);
@@ -373,6 +449,11 @@ public function prepare_items($data = null, $total_items_override = null) {
373449
$params = array_merge($params, [$like, $like, $like]);
374450
}
375451

452+
if ($selected_post_type !== '' && in_array($selected_post_type, $available_post_types, true)) {
453+
$where[] = 'post_type = %s';
454+
$params[] = $selected_post_type;
455+
}
456+
376457
if ($current_view === 'internal') {
377458
$where[] = '(is_internal = 1 OR (is_internal IS NULL AND ' . $internal_sql . '))';
378459
$params = array_merge($params, $internal_params);

tests/AdminListTablesTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
namespace {
44
require_once __DIR__ . '/translation-stubs.php';
5+
6+
if (!function_exists('sanitize_key')) {
7+
function sanitize_key($key)
8+
{
9+
$key = strtolower((string) $key);
10+
11+
return preg_replace('/[^a-z0-9_\-]/', '', $key);
12+
}
13+
}
514
}
615

716
namespace Tests {
@@ -57,6 +66,17 @@ protected function setUp(): void
5766
$param = is_array($key) ? $key : [$key => $value];
5867
return 'admin.php?' . http_build_query($param);
5968
});
69+
Functions\when('get_post_types')->alias(static function ($args = [], $output = 'names') {
70+
return ['post', 'page'];
71+
});
72+
Functions\when('get_post_type_object')->alias(static function ($post_type) {
73+
return (object) [
74+
'labels' => (object) [
75+
'singular_name' => ucfirst((string) $post_type),
76+
],
77+
'label' => ucfirst((string) $post_type),
78+
];
79+
});
6080
Functions\when('wp_timezone')->alias(static fn() => new \DateTimeZone('UTC'));
6181
Functions\when('wp_timezone_string')->alias(static fn() => 'UTC');
6282

@@ -205,6 +225,24 @@ public function test_links_prepare_items_uses_paginated_queries(): void
205225
$this->assertStringContainsString('OFFSET 0', $wpdb->last_get_results_query);
206226
}
207227

228+
public function test_links_prepare_items_filters_by_selected_post_type(): void
229+
{
230+
global $wpdb;
231+
$wpdb = new DummyWpdb();
232+
$wpdb->get_var_return_values = [12];
233+
$expected_items = $this->createItems(3, 'filtered');
234+
$wpdb->results_to_return = $expected_items;
235+
236+
$_GET['post_type'] = 'page';
237+
238+
$table = new \BLC_Links_List_Table();
239+
$table->prepare_items();
240+
241+
$this->assertSame($expected_items, $table->items);
242+
$this->assertStringContainsString("post_type = 'page'", $wpdb->last_get_var_query);
243+
$this->assertStringContainsString("post_type = 'page'", $wpdb->last_get_results_query);
244+
}
245+
208246
public function test_images_columns_display_status_and_timestamp(): void
209247
{
210248
$table = new class() extends \BLC_Images_List_Table {

tests/BlcDashboardLinksPageTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
namespace {
44
require_once __DIR__ . '/translation-stubs.php';
55
require_once __DIR__ . '/stubs/cron-stubs.php';
6+
7+
if (!function_exists('sanitize_key')) {
8+
function sanitize_key($key)
9+
{
10+
$key = strtolower((string) $key);
11+
12+
return preg_replace('/[^a-z0-9_\-]/', '', $key);
13+
}
14+
}
615
}
716

817
namespace Tests {
@@ -171,6 +180,17 @@ public function esc_like($text)
171180
Functions\when('number_format_i18n')->alias(static function ($number, $decimals = 0) {
172181
return number_format((float) $number, (int) $decimals);
173182
});
183+
Functions\when('get_post_types')->alias(static function ($args = [], $output = 'names') {
184+
return ['post', 'page'];
185+
});
186+
Functions\when('get_post_type_object')->alias(static function ($post_type) {
187+
return (object) [
188+
'labels' => (object) [
189+
'singular_name' => ucfirst((string) $post_type),
190+
],
191+
'label' => ucfirst((string) $post_type),
192+
];
193+
});
174194
Functions\when('current_time')->alias(static function ($type, $gmt = 0) {
175195
if ($type === 'timestamp') {
176196
return 1700000000;

0 commit comments

Comments
 (0)