Skip to content

Commit fd4ad69

Browse files
Merge branch 'main' into fix/route-post-redirect
2 parents baba912 + 6c82bca commit fd4ad69

4 files changed

Lines changed: 81 additions & 39 deletions

File tree

.github/workflows/deploy-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
- name: Setup Node.js
3232
uses: actions/setup-node@v6
3333
with:
34-
node-version: 24.15.0
34+
node-version: 24.16.0
3535
cache: npm
3636
cache-dependency-path: website/package-lock.json
3737

src/DataView/Request.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php declare( strict_types=1 );
2+
3+
namespace Tangible\DataView;
4+
5+
use WP_REST_Request;
6+
7+
/**
8+
* Wraps a WP_REST_Request instance, gives access to parameters
9+
* according to method and defines default values
10+
*/
11+
class Request {
12+
13+
/**
14+
* @see https://developer.wordpress.org/reference/classes/wp_rest_request/
15+
*/
16+
protected WP_REST_Request $rest_request;
17+
18+
protected array $default_params = [
19+
'id' => null,
20+
'action' => 'list',
21+
'_wpnonce' => '',
22+
];
23+
24+
public function __construct() {
25+
/**
26+
* Simple implementation based on how WP_REST_Server::serve_request()
27+
* instantiates WP_REST_Request
28+
*
29+
* @see https://developer.wordpress.org/reference/classes/wp_rest_server/serve_request/
30+
*/
31+
$this->rest_request = new WP_REST_Request(
32+
$_SERVER['REQUEST_METHOD'],
33+
$_SERVER['PATH_INFO'] ?? '/'
34+
);
35+
36+
$this->rest_request->set_default_params( $this->default_params );
37+
$this->rest_request->set_query_params( wp_unslash( $_GET ) );
38+
$this->rest_request->set_body_params( wp_unslash( $_POST ) );
39+
}
40+
41+
/**
42+
* Get the current action from the request.
43+
*
44+
* @return string Current action (defaults to 'list').
45+
*/
46+
public function get_current_action(): string {
47+
return sanitize_key( (string) $this->rest_request->get_param( 'action' ) );
48+
}
49+
50+
/**
51+
* Get the entity ID from the current request.
52+
*
53+
* @return int|null Entity ID or null if not present.
54+
*/
55+
public function get_current_id(): ?int {
56+
$id = $this->rest_request->get_param( 'id' );
57+
return $id !== null ? (int) $id : null;
58+
}
59+
60+
/**
61+
* Get the WordPress nonce from the current request.
62+
*/
63+
public function get_nonce(): string {
64+
return (string) $this->rest_request->get_param( '_wpnonce' );
65+
}
66+
67+
/**
68+
* Whether the current request is a POST request.
69+
*/
70+
public function is_post(): bool {
71+
return $this->rest_request->is_method( 'POST' );
72+
}
73+
}

src/DataView/RequestRouter.php

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class RequestRouter {
2424
protected UrlBuilder $url_builder;
2525
protected Renderer $renderer;
2626
protected LabelGenerator $label_generator;
27+
protected Request $request;
2728

2829
/** @var callable|null */
2930
protected $layout_callback = null;
@@ -38,7 +39,8 @@ public function __construct(
3839
FieldTypeRegistry $registry,
3940
UrlBuilder $url_builder,
4041
?Renderer $renderer = null,
41-
?LabelGenerator $label_generator = null
42+
?LabelGenerator $label_generator = null,
43+
?Request $request = null
4244
) {
4345
$this->config = $config;
4446
$this->dataset = $dataset;
@@ -47,6 +49,7 @@ public function __construct(
4749
$this->url_builder = $url_builder;
4850
$this->renderer = $renderer ?? new HtmlRenderer();
4951
$this->label_generator = $label_generator ?? new LabelGenerator();
52+
$this->request = $request ?? new Request();
5053

5154
$this->resolve_labels();
5255
}
@@ -120,8 +123,8 @@ protected function check_capability() {
120123
public function route(): void {
121124
$this->check_capability();
122125

123-
$action = $this->url_builder->get_current_action();
124-
$id = $this->url_builder->get_current_id();
126+
$action = $this->request->get_current_action();
127+
$id = $this->request->get_current_id();
125128

126129
// Handle singular mode differently.
127130
if ( $this->config->is_singular() ) {
@@ -526,15 +529,6 @@ protected function render_list_table( array $entities ): string {
526529
return $html;
527530
}
528531

529-
/**
530-
* Check if this is a POST request.
531-
*
532-
* @return bool True if POST request.
533-
*/
534-
protected function is_post_request(): bool {
535-
return isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST';
536-
}
537-
538532
/**
539533
* Verify nonce for an action.
540534
*
@@ -544,8 +538,7 @@ protected function is_post_request(): bool {
544538
*/
545539
protected function verify_nonce( string $action, ?int $id = null ): bool {
546540
$nonce_action = $this->url_builder->get_nonce_action( $action, $id );
547-
// phpcs:ignore WordPress.Security.NonceVerification.Missing
548-
$nonce = $_POST['_wpnonce'] ?? $_GET['_wpnonce'] ?? '';
541+
$nonce = $this->request->get_nonce();
549542
return wp_verify_nonce( $nonce, $nonce_action ) !== false;
550543
}
551544

src/DataView/UrlBuilder.php

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,30 +50,6 @@ public function url_with_nonce( string $action, ?int $id, string $nonce_action )
5050
return wp_nonce_url( $url, $nonce_action );
5151
}
5252

53-
/**
54-
* Get the current action from the request.
55-
*
56-
* @return string Current action (defaults to 'list').
57-
*/
58-
public function get_current_action(): string {
59-
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
60-
return isset( $_GET['action'] ) ? sanitize_key( $_GET['action'] ) : 'list';
61-
}
62-
63-
/**
64-
* Get the entity ID from the current request.
65-
*
66-
* @return int|null Entity ID or null if not present.
67-
*/
68-
public function get_current_id(): ?int {
69-
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
70-
if ( ! isset( $_GET['id'] ) ) {
71-
return null;
72-
}
73-
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
74-
return (int) $_GET['id'];
75-
}
76-
7753
/**
7854
* Get the menu page slug.
7955
*

0 commit comments

Comments
 (0)