%s', esc_url( $settings_url ), esc_html__( 'Settings', 'aeomatic' ) ) ); return $links; } public function enqueue_assets( string $hook ): void { $is_aeob = false !== strpos( $hook, 'aeomatic' ) || false !== strpos( $hook, 'aeo_booster' ); if ( ! $is_aeob ) { return; } wp_enqueue_style( 'aeob-admin', AEOMATIC_URL . 'assets/css/admin.css', array(), AEOMATIC_VERSION ); wp_enqueue_script( 'aeob-admin', AEOMATIC_URL . 'assets/js/admin.js', array( 'wp-api-fetch', 'wp-i18n' ), AEOMATIC_VERSION, true ); wp_localize_script( 'aeob-admin', 'aeomaticAdmin', array( 'restUrl' => esc_url_raw( rest_url( 'aeomatic/v1/' ) ), 'nonce' => wp_create_nonce( 'wp_rest' ), ) ); if ( false !== strpos( $hook, self::SLUG_ACTIVITY ) || false !== strpos( $hook, str_replace( '-', '_', self::SLUG_ACTIVITY ) ) ) { wp_enqueue_script( 'aeob-verify', AEOMATIC_URL . 'assets/js/verify.js', array( 'wp-api-fetch', 'wp-i18n' ), AEOMATIC_VERSION, true ); } } public function maybe_save(): void { if ( empty( $_POST['aeomatic_save'] ) ) { return; } if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Insufficient permissions.', 'aeomatic' ) ); } check_admin_referer( self::NONCE_ACTION ); // Sanitisation of individual fields is handled recursively inside AEOMATIC_Settings::save(). // The raw array must be passed unslashed so nested sanitisation functions work correctly. $input = isset( $_POST['aeob'] ) ? wp_unslash( $_POST['aeob'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash if ( ! is_array( $input ) ) { $input = array(); } AEOMATIC_Settings::save( $input ); flush_rewrite_rules(); AEOMATIC_Activity::log( 'settings_saved', __( 'Settings updated.', 'aeomatic' ) ); add_settings_error( 'aeomatic_messages', 'aeomatic_saved', __( 'Settings saved.', 'aeomatic' ), 'updated' ); } public function render_dashboard(): void { require AEOMATIC_DIR . 'admin/views/dashboard.php'; } public function render_activity(): void { require AEOMATIC_DIR . 'admin/views/activity.php'; } public function render_settings(): void { require AEOMATIC_DIR . 'admin/views/settings.php'; } /** * Dismiss the review notice permanently when the user clicks "Already did" or "×". */ public function maybe_dismiss_review(): void { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( ! isset( $_GET['aeomatic_dismiss_review'] ) ) { return; } if ( ! current_user_can( 'manage_options' ) ) { return; } update_option( 'aeomatic_review_dismissed', true, false ); // Redirect back cleanly without the query param. $redirect = remove_query_arg( 'aeomatic_dismiss_review' ); wp_safe_redirect( $redirect ); exit; } /** * Show a friendly review request notice after 7 days of use. * Only shown to admins, only in wp-admin, dismissed permanently on click. */ public function maybe_show_review_notice(): void { // Already dismissed. if ( get_option( 'aeomatic_review_dismissed' ) ) { return; } // Only admins see this. if ( ! current_user_can( 'manage_options' ) ) { return; } // Wait 7 days after install. $installed_at = (int) AEOMATIC_Settings::get( '_meta', 'installed_at' ); if ( ! $installed_at || ( time() - $installed_at ) < 7 * DAY_IN_SECONDS ) { return; } $review_url = 'https://wordpress.org/support/plugin/aeomatic/reviews/#new-post'; $dismiss_url = add_query_arg( 'aeomatic_dismiss_review', '1' ); ?>