PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.3
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.3
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / elementor / infrastructure / request-post.php

request-post.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.3, at src/elementor/infrastructure/request-post.php

137 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Elementor\Infrastructure;
4
5 use WP_Post;
6
7 /**
8 * Retrieve the WP_Post from the request.
9 */
10 class Request_Post {
11
12 /**
13 * Retrieves the WP_Post, applicable to the current request.
14 *
15 * @return WP_Post|null
16 */
17 public function get_post(): ?WP_Post {
18 return \get_post( $this->get_post_id() );
19 }
20
21 /**
22 * Retrieves the post ID, applicable to the current request.
23 *
24 * @return int|null The post ID.
25 */
26 public function get_post_id(): ?int {
27 switch ( $this->get_server_request_method() ) {
28 case 'GET':
29 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
30 if ( isset( $_GET['post'] ) && \is_numeric( $_GET['post'] ) ) {
31 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended -- Reason: No sanitization needed because we cast to an integer,We are not processing form information.
32 return (int) \wp_unslash( $_GET['post'] );
33 }
34
35 break;
36 case 'POST':
37 // Only allow POST requests when doing AJAX.
38 if ( ! \wp_doing_ajax() ) {
39 break;
40 }
41
42 switch ( $this->get_post_action() ) {
43 // Our Yoast SEO form submission, it should include `post_id`.
44 case 'wpseo_elementor_save':
45 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: We are not processing form information.
46 if ( isset( $_POST['post_id'] ) && \is_numeric( $_POST['post_id'] ) ) {
47 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Missing -- Reason: No sanitization needed because we cast to an integer,We are not processing form information.
48 return (int) \wp_unslash( $_POST['post_id'] );
49 }
50
51 break;
52 // Elementor editor AJAX request.
53 case 'elementor_ajax':
54 return $this->get_document_id();
55 }
56
57 break;
58 }
59
60 return null;
61 }
62
63 /**
64 * Returns the server request method.
65 *
66 * @return string|null The server request method, in upper case.
67 */
68 private function get_server_request_method(): ?string {
69 if ( ! isset( $_SERVER['REQUEST_METHOD'] ) ) {
70 return null;
71 }
72
73 if ( ! \is_string( $_SERVER['REQUEST_METHOD'] ) ) {
74 return null;
75 }
76
77 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are only comparing it later.
78 return \strtoupper( \wp_unslash( $_SERVER['REQUEST_METHOD'] ) );
79 }
80
81 /**
82 * Retrieves the action from the POST request.
83 *
84 * @return string|null The action or null if not found.
85 */
86 private function get_post_action(): ?string {
87 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: We are not processing form information.
88 if ( isset( $_POST['action'] ) && \is_string( $_POST['action'] ) ) {
89 // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, we are only strictly comparing.
90 return (string) \wp_unslash( $_POST['action'] );
91 }
92
93 return null;
94 }
95
96 /**
97 * Retrieves the document ID from the POST request.
98 *
99 * Note: this is specific to Elementor' `elementor_ajax` action. And then the `get_document_config` internal action.
100 * Currently, you can see this in play when:
101 * - showing the Site Settings in the Elementor editor
102 * - going to another Recent post/page in the Elementor editor V2
103 *
104 * @return int|null The document ID or null if not found.
105 */
106 private function get_document_id(): ?int {
107 // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: We are not processing form information.
108 if ( ! ( isset( $_POST['actions'] ) && \is_string( $_POST['actions'] ) ) ) {
109 return null;
110 }
111
112 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Missing -- Reason: No sanitization needed because we cast to an integer (after JSON decode and type/exist checks),We are not processing form information.
113 $actions = \json_decode( \wp_unslash( $_POST['actions'] ), true );
114 if ( ! \is_array( $actions ) ) {
115 return null;
116 }
117
118 // Elementor sends everything in a `document-{ID}` format.
119 $action = \array_shift( $actions );
120 if ( $action === null ) {
121 return null;
122 }
123
124 // There are multiple action types. We only care about the "get_document_config" one.
125 if ( ! ( isset( $action['action'] ) && $action['action'] === 'get_document_config' ) ) {
126 return null;
127 }
128
129 // Return the ID from the data, if it is set and numeric.
130 if ( isset( $action['data']['id'] ) && \is_numeric( $action['data']['id'] ) ) {
131 return (int) $action['data']['id'];
132 }
133
134 return null;
135 }
136 }
137