@@ -744,14 +744,14 @@ public function change_settings_on_save( array $settings, array $input = array()
744744 $ validation = $ this ->validate_freemius_plugins_for_save ( $ settings );
745745 $ errors = $ validation ['errors ' ];
746746
747- // Persist only validated plugin rows.
747+ // Persist validated rows and preserve existing saved rows for invalid entries .
748748 $ settings ['plugins ' ] = $ validation ['plugins ' ];
749749
750750 if ( ! empty ( $ errors ) ) {
751751 add_settings_error (
752752 self ::$ prefix . '-notices ' ,
753753 self ::$ prefix . '_freemius_validation_partial ' ,
754- esc_html__ ( 'Some Freemius plugin rows failed validation and were not saved . ' , 'freemkit ' ),
754+ esc_html__ ( 'Some Freemius plugin rows failed validation. Existing saved values were kept for those rows . ' , 'freemkit ' ),
755755 'error '
756756 );
757757
@@ -776,9 +776,24 @@ public function change_settings_on_save( array $settings, array $input = array()
776776 * @return array{plugins: array<int,mixed>, errors: array<int,string>} Filtered rows and validation errors.
777777 */
778778 private function validate_freemius_plugins_for_save ( array $ settings ): array {
779- $ errors = array ();
780- $ valid_plugins = array ();
781- $ plugins = isset ( $ settings ['plugins ' ] ) && is_array ( $ settings ['plugins ' ] ) ? $ settings ['plugins ' ] : array ();
779+ $ errors = array ();
780+ $ persisted_plugins = array ();
781+ $ plugins = isset ( $ settings ['plugins ' ] ) && is_array ( $ settings ['plugins ' ] ) ? $ settings ['plugins ' ] : array ();
782+ $ existing_settings = get_option ( Options_API::SETTINGS_OPTION , array () );
783+ $ existing_plugins = ( is_array ( $ existing_settings ) && isset ( $ existing_settings ['plugins ' ] ) && is_array ( $ existing_settings ['plugins ' ] ) )
784+ ? $ existing_settings ['plugins ' ]
785+ : array ();
786+
787+ $ existing_by_row_id = array ();
788+ foreach ( $ existing_plugins as $ existing_plugin ) {
789+ if ( ! is_array ( $ existing_plugin ) ) {
790+ continue ;
791+ }
792+ $ row_id = isset ( $ existing_plugin ['row_id ' ] ) ? (string ) $ existing_plugin ['row_id ' ] : '' ;
793+ if ( '' !== $ row_id ) {
794+ $ existing_by_row_id [ $ row_id ] = $ existing_plugin ;
795+ }
796+ }
782797
783798 foreach ( $ plugins as $ index => $ plugin ) {
784799 if ( ! is_array ( $ plugin ) || ! isset ( $ plugin ['fields ' ] ) || ! is_array ( $ plugin ['fields ' ] ) ) {
@@ -798,26 +813,45 @@ private function validate_freemius_plugins_for_save( array $settings ): array {
798813
799814 if ( '' === $ plugin_id || '' === $ public_key || '' === $ secret_key ) {
800815 /* translators: %s: plugin row label. */
801- $ errors [] = sprintf ( esc_html__ ( '%s: Product ID, Public Key, and Secret Key are required. ' , 'freemkit ' ), esc_html ( $ label ) );
816+ $ errors [] = sprintf ( esc_html__ ( '%s: Product ID, Public Key, and Secret Key are required. ' , 'freemkit ' ), esc_html ( $ label ) );
817+ $ persisted_plugins [] = $ this ->resolve_saved_or_submitted_plugin_row ( $ plugin , $ existing_by_row_id );
802818 continue ;
803819 }
804820
805821 $ result = $ this ->validate_freemius_credentials ( $ plugin_id , $ public_key , $ secret_key );
806822 if ( is_wp_error ( $ result ) ) {
807823 /* translators: 1: plugin row label, 2: validation error message. */
808- $ errors [] = sprintf ( esc_html__ ( '%1$s: %2$s ' , 'freemkit ' ), esc_html ( $ label ), esc_html ( $ result ->get_error_message () ) );
824+ $ errors [] = sprintf ( esc_html__ ( '%1$s: %2$s ' , 'freemkit ' ), esc_html ( $ label ), esc_html ( $ result ->get_error_message () ) );
825+ $ persisted_plugins [] = $ this ->resolve_saved_or_submitted_plugin_row ( $ plugin , $ existing_by_row_id );
809826 continue ;
810827 }
811828
812- $ valid_plugins [] = $ plugin ;
829+ $ persisted_plugins [] = $ plugin ;
813830 }
814831
815832 return array (
816- 'plugins ' => array_values ( $ valid_plugins ),
833+ 'plugins ' => array_values ( $ persisted_plugins ),
817834 'errors ' => $ errors ,
818835 );
819836 }
820837
838+ /**
839+ * Return existing saved plugin row when possible, otherwise submitted row.
840+ *
841+ * @param array $submitted_plugin Submitted plugin row.
842+ * @param array $existing_by_row_id Existing rows indexed by row_id.
843+ * @return array
844+ */
845+ private function resolve_saved_or_submitted_plugin_row ( array $ submitted_plugin , array $ existing_by_row_id ): array {
846+ $ row_id = isset ( $ submitted_plugin ['row_id ' ] ) ? (string ) $ submitted_plugin ['row_id ' ] : '' ;
847+
848+ if ( '' !== $ row_id && isset ( $ existing_by_row_id [ $ row_id ] ) && is_array ( $ existing_by_row_id [ $ row_id ] ) ) {
849+ return $ existing_by_row_id [ $ row_id ];
850+ }
851+
852+ return $ submitted_plugin ;
853+ }
854+
821855 /**
822856 * Handle AJAX search for ConvertKit resources
823857 *
0 commit comments