Skip to content

Commit d288841

Browse files
authored
Merge pull request #764 from ProgressPlanner/filip/fix-main-ci-checks
Fix PHPStan errors and phpunit CVE on main
2 parents fbfa632 + 5a0358c commit d288841

15 files changed

Lines changed: 317 additions & 210 deletions

classes/admin/class-page-settings.php

Lines changed: 54 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,6 @@
1414
*/
1515
class Page_Settings {
1616

17-
/**
18-
* Constructor.
19-
*/
20-
public function __construct() {
21-
// Add the admin menu page.
22-
\add_action( 'admin_menu', [ $this, 'add_admin_menu_page' ] );
23-
24-
// Add AJAX hooks to save options.
25-
\add_action( 'wp_ajax_prpl_settings_form', [ $this, 'store_settings_form_options' ] );
26-
}
27-
28-
/**
29-
* Add admin-menu page, as a submenu in the progress-planner menu.
30-
*
31-
* @return void
32-
*/
33-
public function add_admin_menu_page() {
34-
\add_submenu_page(
35-
'progress-planner',
36-
\esc_html__( 'Settings', 'progress-planner' ),
37-
\esc_html__( 'Settings', 'progress-planner' ),
38-
'manage_options',
39-
'progress-planner-settings',
40-
[ $this, 'add_admin_page_content' ]
41-
);
42-
}
43-
44-
/**
45-
* Add content to the admin page of the free plugin.
46-
*
47-
* @return void
48-
*/
49-
public function add_admin_page_content() {
50-
require_once PROGRESS_PLANNER_DIR . '/views/admin-page-settings.php';
51-
}
52-
5317
/**
5418
* Get an array of settings.
5519
*
@@ -58,27 +22,28 @@ public function add_admin_page_content() {
5822
public function get_settings() {
5923
$settings = [];
6024
foreach ( \progress_planner()->get_page_types()->get_page_types() as $page_type ) {
61-
if ( ! $this->should_show_setting( $page_type['slug'] ) ) {
25+
$slug = (string) $page_type['slug']; // @phpstan-ignore offsetAccess.invalidOffset
26+
if ( ! $this->should_show_setting( $slug ) ) {
6227
continue;
6328
}
6429

65-
$settings[ $page_type['slug'] ] = [
66-
'id' => $page_type['slug'],
30+
$settings[ $slug ] = [
31+
'id' => $slug,
6732
'value' => '_no_page_needed',
6833
'isset' => 'no',
69-
'title' => $page_type['title'],
70-
'description' => $page_type['description'] ?? '',
34+
'title' => $page_type['title'], // @phpstan-ignore offsetAccess.invalidOffset
35+
'description' => $page_type['description'] ?? '', // @phpstan-ignore offsetAccess.invalidOffset
7136
'type' => 'page-select',
72-
'page' => $page_type['slug'],
37+
'page' => $slug,
7338
];
7439

75-
if ( \progress_planner()->get_page_types()->is_page_needed( $page_type['slug'] ) ) {
76-
$type_pages = \progress_planner()->get_page_types()->get_posts_by_type( 'any', $page_type['slug'] );
40+
if ( \progress_planner()->get_page_types()->is_page_needed( $slug ) ) {
41+
$type_pages = \progress_planner()->get_page_types()->get_posts_by_type( 'any', $slug );
7742
if ( empty( $type_pages ) ) {
78-
$settings[ $page_type['slug'] ]['value'] = \progress_planner()->get_page_types()->get_default_page_id_by_type( $page_type['slug'] );
43+
$settings[ $slug ]['value'] = \progress_planner()->get_page_types()->get_default_page_id_by_type( $slug );
7944
} else {
80-
$settings[ $page_type['slug'] ]['value'] = $type_pages[0]->ID;
81-
$settings[ $page_type['slug'] ]['isset'] = 'yes';
45+
$settings[ $slug ]['value'] = $type_pages[0]->ID;
46+
$settings[ $slug ]['isset'] = 'yes';
8247

8348
// If there is more than one page, we need to check if the page has a parent with the same page-type assigned.
8449
if ( 1 < \count( $type_pages ) ) {
@@ -89,7 +54,7 @@ public function get_settings() {
8954
foreach ( $type_pages as $type_page ) {
9055
$parent = \get_post_field( 'post_parent', $type_page->ID );
9156
if ( $parent && \in_array( (int) $parent, $type_pages_ids, true ) ) {
92-
$settings[ $page_type['slug'] ]['value'] = $parent;
57+
$settings[ $slug ]['value'] = $parent;
9358
break;
9459
}
9560
}
@@ -123,95 +88,76 @@ public function should_show_setting( $page_type ) {
12388
}
12489

12590
/**
126-
* Store the settings form options.
91+
* Set the page value.
92+
*
93+
* @param array $pages The pages.
12794
*
12895
* @return void
12996
*/
130-
public function store_settings_form_options() {
97+
public function set_page_values( $pages ) {
13198

132-
if ( ! \current_user_can( 'manage_options' ) ) {
133-
\wp_send_json_error( [ 'message' => \esc_html__( 'You do not have permission to update settings.', 'progress-planner' ) ] );
99+
if ( empty( $pages ) ) {
100+
return;
134101
}
135102

136-
// Use check_ajax_referer instead of check_admin_referer for AJAX handlers.
137-
// check_admin_referer is designed for form submissions, not AJAX requests.
138-
if ( ! \check_ajax_referer( 'progress_planner', 'nonce', false ) ) {
139-
\wp_send_json_error( [ 'message' => \esc_html__( 'Invalid nonce.', 'progress-planner' ) ] );
140-
}
141-
142-
if ( isset( $_POST['pages'] ) ) {
143-
// Sanitize the pages array at point of reception.
144-
$pages = \map_deep( \wp_unslash( $_POST['pages'] ), 'sanitize_text_field' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
145-
146-
foreach ( $pages as $type => $page_args ) {
147-
$need_page = isset( $page_args['have_page'] ) ? $page_args['have_page'] : '';
103+
foreach ( $pages as $type => $page_args ) {
104+
$need_page = isset( $page_args['have_page'] ) ? $page_args['have_page'] : '';
148105

149-
\progress_planner()->get_page_types()->set_no_page_needed(
150-
$type,
151-
'not-applicable' === $need_page
152-
);
153-
154-
// Remove the post-meta from the existing posts.
155-
$existing_posts = \progress_planner()->get_page_types()->get_posts_by_type( 'any', $type );
156-
foreach ( $existing_posts as $post ) {
157-
if ( $post->ID === (int) $page_args['id'] && 'no' !== $page_args['have_page'] ) {
158-
continue;
159-
}
106+
\progress_planner()->get_page_types()->set_no_page_needed(
107+
$type,
108+
'not-applicable' === $need_page
109+
);
160110

161-
// Get the term-ID for the type.
162-
$term = \get_term_by( 'slug', $type, Page_Types::TAXONOMY_NAME );
163-
if ( ! $term instanceof \WP_Term ) {
164-
continue;
165-
}
166-
167-
// Remove the assigned terms from the `progress_planner_page_types` taxonomy.
168-
\wp_remove_object_terms( $post->ID, $term->term_id, Page_Types::TAXONOMY_NAME );
111+
// Remove the post-meta from the existing posts.
112+
$existing_posts = \progress_planner()->get_page_types()->get_posts_by_type( 'any', $type );
113+
foreach ( $existing_posts as $post ) {
114+
if ( $post->ID === (int) $page_args['id'] && 'no' !== $page_args['have_page'] ) {
115+
continue;
169116
}
170117

171-
// Skip if the ID is not set.
172-
if ( ! isset( $page_args['id'] ) || 1 > (int) $page_args['id'] ) {
118+
// Get the term-ID for the type.
119+
$term = \get_term_by( 'slug', $type, Page_Types::TAXONOMY_NAME );
120+
if ( ! $term instanceof \WP_Term ) {
173121
continue;
174122
}
175123

176-
if ( 'no' !== $page_args['have_page'] ) {
177-
// Add the term to the `progress_planner_page_types` taxonomy.
178-
\progress_planner()->get_page_types()->set_page_type_by_id( (int) $page_args['id'], $type );
179-
}
124+
// Remove the assigned terms from the `progress_planner_page_types` taxonomy.
125+
\wp_remove_object_terms( $post->ID, $term->term_id, Page_Types::TAXONOMY_NAME );
180126
}
181-
}
182-
183-
$this->save_settings();
184-
$this->save_post_types();
185127

186-
\do_action( 'progress_planner_settings_form_options_stored' );
128+
// Skip if the ID is not set.
129+
if ( ! isset( $page_args['id'] ) || 1 > (int) $page_args['id'] ) {
130+
continue;
131+
}
187132

188-
\wp_send_json_success( \esc_html__( 'Options stored successfully', 'progress-planner' ) );
133+
if ( 'no' !== $page_args['have_page'] ) {
134+
// Add the term to the `progress_planner_page_types` taxonomy.
135+
\progress_planner()->get_page_types()->set_page_type_by_id( (int) $page_args['id'], $type );
136+
}
137+
}
189138
}
190139

191140
/**
192-
* Save the settings.
141+
* Save the redirect on login setting.
142+
*
143+
* @param bool $redirect_on_login Whether to redirect on login.
193144
*
194145
* @return void
195146
*/
196-
public function save_settings() {
197-
// Nonce is already checked in store_settings_form_options() which calls this method.
198-
$redirect_on_login = isset( $_POST['prpl-redirect-on-login'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
199-
? \sanitize_text_field( \wp_unslash( $_POST['prpl-redirect-on-login'] ) ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
200-
: false;
201-
202-
\update_user_meta( \get_current_user_id(), 'prpl_redirect_on_login', (bool) $redirect_on_login );
147+
public function save_redirect_on_login( $redirect_on_login = false ) {
148+
\update_user_meta( \get_current_user_id(), 'prpl_redirect_on_login', $redirect_on_login );
203149
}
204150

205151
/**
206152
* Save the post types.
207153
*
154+
* @param array $post_types The post types.
155+
*
208156
* @return void
209157
*/
210-
public function save_post_types() {
211-
// Nonce is already checked in store_settings_form_options() which calls this method.
212-
$include_post_types = isset( $_POST['prpl-post-types-include'] ) // phpcs:ignore WordPress.Security.NonceVerification.Missing
213-
? \array_map( 'sanitize_text_field', \wp_unslash( $_POST['prpl-post-types-include'] ) ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
214-
// If no post types are selected, use the default post types (post and page can be deregistered).
158+
public function save_post_types( $post_types = [] ) {
159+
$include_post_types = ! empty( $post_types )
160+
? $post_types
215161
: \array_intersect( [ 'post', 'page' ], \progress_planner()->get_settings()->get_public_post_types() );
216162

217163
\progress_planner()->get_settings()->set( 'include_post_types', $include_post_types );

classes/admin/widgets/class-activity-scores.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ public function get_checklist_results() {
9898
$items = $this->get_checklist();
9999
$results = [];
100100
foreach ( $items as $item ) {
101-
$results[ $item['label'] ] = $item['callback']();
101+
$label = (string) $item['label']; // @phpstan-ignore offsetAccess.invalidOffset
102+
$results[ $label ] = $item['callback'](); // @phpstan-ignore offsetAccess.invalidOffset
102103
}
103104
return $results;
104105
}

classes/class-base.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ class Base {
8686
*/
8787
public function init() {
8888
if ( ! \function_exists( 'current_user_can' ) ) {
89-
require_once ABSPATH . 'wp-includes/capabilities.php'; // @phpstan-ignore requireOnce.fileNotFound
89+
// @phpstan-ignore-next-line requireOnce.fileNotFound
90+
require_once ABSPATH . 'wp-includes/capabilities.php';
9091
}
9192
if ( ! \function_exists( 'wp_get_current_user' ) ) {
92-
require_once ABSPATH . 'wp-includes/pluggable.php'; // @phpstan-ignore requireOnce.fileNotFound
93+
// @phpstan-ignore-next-line requireOnce.fileNotFound
94+
require_once ABSPATH . 'wp-includes/pluggable.php';
9395
}
9496

9597
if ( \defined( '\IS_PLAYGROUND_PREVIEW' ) && \constant( '\IS_PLAYGROUND_PREVIEW' ) === true ) {
@@ -380,7 +382,8 @@ public function get_file_version( $file ) {
380382

381383
// Otherwise, use the plugin header.
382384
if ( ! \function_exists( 'get_file_data' ) ) {
383-
require_once ABSPATH . 'wp-includes/functions.php'; // @phpstan-ignore requireOnce.fileNotFound
385+
// @phpstan-ignore-next-line requireOnce.fileNotFound
386+
require_once ABSPATH . 'wp-includes/functions.php';
384387
}
385388

386389
if ( ! self::$plugin_version ) {

classes/class-suggested-tasks.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ public function rest_api_tax_query( $args, $request ) {
479479

480480
// Handle sorting parameters.
481481
if ( isset( $request['filter']['orderby'] ) ) {
482+
// @phpstan-ignore-next-line argument.templateType
482483
$args['orderby'] = \sanitize_sql_orderby( $request['filter']['orderby'] );
483484
}
484485
if ( isset( $request['filter']['order'] ) ) {

classes/suggested-tasks/class-task.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,12 +183,14 @@ public function get_rest_formatted_data( $post_id = null ): array {
183183

184184
// Make sure WP_REST_Posts_Controller is loaded.
185185
if ( ! \class_exists( 'WP_REST_Posts_Controller' ) ) {
186-
require_once ABSPATH . 'wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php'; // @phpstan-ignore requireOnce.fileNotFound
186+
// @phpstan-ignore-next-line requireOnce.fileNotFound
187+
require_once ABSPATH . 'wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php';
187188
}
188189

189190
// Make sure WP_REST_Request is loaded.
190191
if ( ! \class_exists( 'WP_REST_Request' ) ) {
191-
require_once ABSPATH . 'wp-includes/rest-api/class-wp-rest-request.php'; // @phpstan-ignore requireOnce.fileNotFound
192+
// @phpstan-ignore-next-line requireOnce.fileNotFound
193+
require_once ABSPATH . 'wp-includes/rest-api/class-wp-rest-request.php';
192194
}
193195

194196
// Use the appropriate controller for the post type.

classes/suggested-tasks/data-collector/class-inactive-plugins.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ public function update_inactive_plugins_cache() {
4747
*/
4848
protected function calculate_data() {
4949
if ( ! \function_exists( 'get_plugins' ) ) {
50-
require_once ABSPATH . 'wp-admin/includes/plugin.php'; // @phpstan-ignore requireOnce.fileNotFound
50+
// @phpstan-ignore-next-line requireOnce.fileNotFound
51+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
5152
}
5253

5354
// Clear the plugins cache, so get_plugins() returns the latest plugins.

classes/suggested-tasks/providers/class-core-update.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ public function add_core_update_link( $update_actions ) {
107107
public function should_add_task() {
108108
// Without this \wp_get_update_data() might not return correct data for the core updates (depending on the timing).
109109
if ( ! \function_exists( 'get_core_updates' ) ) {
110-
require_once ABSPATH . 'wp-admin/includes/update.php'; // @phpstan-ignore requireOnce.fileNotFound
110+
// @phpstan-ignore-next-line requireOnce.fileNotFound
111+
require_once ABSPATH . 'wp-admin/includes/update.php';
111112
}
112113

113114
// For wp_get_update_data() to return correct data it needs to be called after the 'admin_init' action (with priority 10).

classes/suggested-tasks/providers/class-fewer-tags.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ public function is_task_completed( $task_id = '' ) {
154154
protected function is_plugin_active() {
155155
if ( null === $this->is_plugin_active ) {
156156
if ( ! \function_exists( 'get_plugins' ) ) {
157-
require_once ABSPATH . 'wp-admin/includes/plugin.php'; // @phpstan-ignore requireOnce.fileNotFound
157+
// @phpstan-ignore-next-line requireOnce.fileNotFound
158+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
158159
}
159160

160161
$plugins = \get_plugins();

classes/suggested-tasks/providers/class-select-locale.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ public function print_popover_instructions() {
205205
public function print_popover_form_contents() {
206206

207207
if ( ! \function_exists( 'wp_get_available_translations' ) ) {
208-
require_once ABSPATH . 'wp-admin/includes/translation-install.php'; // @phpstan-ignore requireOnce.fileNotFound
208+
// @phpstan-ignore-next-line requireOnce.fileNotFound
209+
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
209210
}
210211

211212
$languages = \get_available_languages();
@@ -277,7 +278,8 @@ public function handle_interactive_task_specific_submit() {
277278

278279
// Handle translation installation.
279280
if ( \current_user_can( 'install_languages' ) ) {
280-
require_once ABSPATH . 'wp-admin/includes/translation-install.php'; // @phpstan-ignore requireOnce.fileNotFound
281+
// @phpstan-ignore-next-line requireOnce.fileNotFound
282+
require_once ABSPATH . 'wp-admin/includes/translation-install.php';
281283

282284
if ( \wp_can_install_language_pack() ) {
283285
$language = \wp_download_language_pack( $language_for_update );

0 commit comments

Comments
 (0)