Skip to content

Commit 7a279fe

Browse files
committed
feat: Add Freemius credential validation with blocking wizard step progression and save-time enforcement
- Add process_step method to Settings_Wizard with blocking validation error handling - Implement has_blocking_validation_error to check for Freemius validation failures - Add ajax_validate_freemius_keys endpoint for real-time credential verification - Enforce validation on save via validate_freemius_plugins_for_save with row-level filtering - Add validate_freemius_credentials method with FS signature
1 parent 5ceba57 commit 7a279fe

8 files changed

Lines changed: 808 additions & 67 deletions

includes/admin/class-settings-wizard.php

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,80 @@ public function get_wizard_steps(): array {
146146
return apply_filters( 'freemkit_wizard_steps', $steps );
147147
}
148148

149+
/**
150+
* Process wizard step submission with support for blocking validation errors.
151+
*
152+
* @return void
153+
*/
154+
public function process_step() {
155+
if ( empty( $_POST['wizard_action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
156+
return;
157+
}
158+
159+
$nonce_value = isset( $_POST[ $this->prefix . '_wizard_nonce' ] ) ? sanitize_text_field( wp_unslash( $_POST[ $this->prefix . '_wizard_nonce' ] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
160+
if ( empty( $nonce_value ) || ! wp_verify_nonce( $nonce_value, $this->prefix . '_wizard_nonce' ) ) {
161+
return;
162+
}
163+
164+
if ( ! current_user_can( 'manage_options' ) ) {
165+
return;
166+
}
167+
168+
$this->current_step = $this->get_current_step();
169+
$action = isset( $_POST['wizard_action'] ) ? sanitize_text_field( wp_unslash( $_POST['wizard_action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
170+
171+
switch ( $action ) {
172+
case 'next_step':
173+
$this->process_current_step();
174+
if ( $this->has_blocking_validation_error() ) {
175+
$this->redirect_to_step( $this->current_step );
176+
}
177+
$this->next_step();
178+
$this->redirect_to_step( $this->current_step );
179+
break;
180+
181+
case 'previous_step':
182+
$this->previous_step();
183+
$this->redirect_to_step( $this->current_step );
184+
break;
185+
186+
case 'finish_setup':
187+
$this->process_current_step();
188+
if ( $this->has_blocking_validation_error() ) {
189+
$this->redirect_to_step( $this->current_step );
190+
}
191+
$this->mark_wizard_completed();
192+
$this->redirect_to_step( $this->total_steps + 1 );
193+
break;
194+
195+
case 'skip_wizard':
196+
$this->mark_wizard_completed();
197+
$this->redirect_to_admin();
198+
break;
199+
default:
200+
break;
201+
}
202+
}
203+
204+
/**
205+
* Check if a blocking Freemius validation error is present.
206+
*
207+
* @return bool
208+
*/
209+
private function has_blocking_validation_error(): bool {
210+
$errors = get_settings_errors( $this->prefix . '-notices' );
211+
212+
foreach ( $errors as $error ) {
213+
$code = (string) $error['code'];
214+
$type = (string) $error['type'];
215+
if ( $this->prefix . '_freemius_validation_failed' === $code && 'error' === $type ) {
216+
return true;
217+
}
218+
}
219+
220+
return false;
221+
}
222+
149223
/**
150224
* Build settings array for a wizard step from setting keys.
151225
*
@@ -342,7 +416,7 @@ public function enqueue_wizard_support_scripts( string $hook ): void {
342416

343417
$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
344418
$admin_path = "/js/admin{$suffix}.js";
345-
$kit_path = "/js/kit-validate{$suffix}.js";
419+
$kit_path = "/js/connection-validate{$suffix}.js";
346420

347421
$admin_file = __DIR__ . $admin_path;
348422
$kit_file = __DIR__ . $kit_path;
@@ -358,7 +432,7 @@ public function enqueue_wizard_support_scripts( string $hook ): void {
358432
);
359433

360434
wp_enqueue_script(
361-
'freemkit-kit-validate',
435+
'freemkit-connection-validate',
362436
plugins_url( $kit_path, __FILE__ ),
363437
array( 'jquery' ),
364438
$kit_version,
@@ -375,11 +449,15 @@ public function enqueue_wizard_support_scripts( string $hook ): void {
375449
'nonce' => wp_create_nonce( $this->prefix . '_admin_nonce' ),
376450
'webhook_urls' => Settings::get_webhook_urls(),
377451
'strings' => array(
378-
'cache_cleared' => esc_html__( 'Cache cleared successfully!', 'freemkit' ),
379-
'cache_error' => esc_html__( 'Error clearing cache: ', 'freemkit' ),
380-
'api_validation_error' => esc_html__( 'Error validating API credentials.', 'freemkit' ),
381-
'copy_success' => esc_html__( 'Webhook URL copied.', 'freemkit' ),
382-
'copy_failed' => esc_html__( 'Copy failed. Select and copy manually.', 'freemkit' ),
452+
'cache_cleared' => esc_html__( 'Cache cleared successfully!', 'freemkit' ),
453+
'cache_error' => esc_html__( 'Error clearing cache: ', 'freemkit' ),
454+
'api_validation_error' => esc_html__( 'Error validating API credentials.', 'freemkit' ),
455+
'validate_freemius_keys' => esc_html__( 'Validate Keys', 'freemkit' ),
456+
'freemius_missing_fields' => esc_html__( 'Product ID, public key, and secret key are required.', 'freemkit' ),
457+
'freemius_validation_success' => esc_html__( 'Freemius credentials are valid.', 'freemkit' ),
458+
'freemius_validation_error' => esc_html__( 'Unable to validate Freemius credentials.', 'freemkit' ),
459+
'copy_success' => esc_html__( 'Webhook URL copied.', 'freemkit' ),
460+
'copy_failed' => esc_html__( 'Copy failed. Select and copy manually.', 'freemkit' ),
383461
),
384462
)
385463
);

0 commit comments

Comments
 (0)