Skip to content

Fix/add data removing option#1251

Open
sapayth wants to merge 13 commits intoweDevsOfficial:developfrom
sapayth:fix/add-data-removing-option
Open

Fix/add data removing option#1251
sapayth wants to merge 13 commits intoweDevsOfficial:developfrom
sapayth:fix/add-data-removing-option

Conversation

@sapayth
Copy link
Member

@sapayth sapayth commented Mar 9, 2022

In User Frontend > Tools a new setting is introduced to delete some data upon plugin deletion. When you delete the WP User Frontend version, it will also delete all the data related to WP User Frontend Pro as well. This won't happen when the plugins are deactivated.

  1. Delete Plugin Settings on Uninstall
  2. Delete Database Tables on Uninstall
  3. Delete WPUF Forms on Uninstall
  4. Delete WPUF Pages on Uninstall

Settings that will be removed are:
all options containing wpuf_

DB tables that will be removed are:

  1. wpuf_transaction
  2. wpuf_subscribers
  3. wpuf_message
  4. wpuf_activity

All pages containing wpuf shortcode

Summary by CodeRabbit

  • New Features
    • Uninstall settings panel with persistent toggles (delete settings, database, forms, pages) and a caution block explaining data removal.
    • Form export to downloadable JSON for all or selected forms (including registration forms).
    • Form import via JSON uploader with progress/feedback UI.
    • Admin Tools page with maintenance actions and bulk form management/export/import options.

@sapayth sapayth added needs: dev review This PR needs review by a developer and removed second-opinion labels Apr 22, 2022
@FaraziF FaraziF added QA Approved This PR is approved by the QA team and removed needs: testing labels May 9, 2022
@sapayth sapayth removed the needs: dev review This PR needs review by a developer label Nov 25, 2022
@Rat01047
Copy link
Contributor

Rat01047 commented Dec 5, 2022

Issue:
Cannot Sign-In into Admin after deleting Plugin with options activated via Tools

Scenario:
WPUF > Tools > Clicked all the Options built in this PR > Deleted Plugin > Cannot access Admin Dashboard

@Rat01047 Rat01047 self-assigned this Dec 6, 2022
@sapayth
Copy link
Member Author

sapayth commented Dec 6, 2022

Issue: Cannot Sign-In into Admin after deleting Plugin with options activated via Tools

Scenario: WPUF > Tools > Clicked all the Options built in this PR > Deleted Plugin > Cannot access Admin Dashboard

Seems ok from my end. Would you please test again?

@Rat01047
Copy link
Contributor

Rat01047 commented Dec 7, 2022

Issue: Cannot Sign-In into Admin after deleting Plugin with options activated via Tools
Scenario: WPUF > Tools > Clicked all the Options built in this PR > Deleted Plugin > Cannot access Admin Dashboard

Seems ok from my end. Would you please test again?

Still exists, when you select all the options and then Delete the Plugin

@sapayth sapayth added dev: on-progress and removed QA Approved This PR is approved by the QA team labels Dec 12, 2022
@Rat01047 Rat01047 added the bug label Dec 20, 2022
@anik-fahmid anik-fahmid assigned sapayth and unassigned Rat01047 Jan 6, 2023
@Rat01047
Copy link
Contributor

@sapayth the issue still exists, selecting all the settings given in PR and then uninstalling plugin > takes away admin's ability to access site

Screenshot for reference:
https://tinyurl.com/yrtfx389

@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a71d58e9-b459-4530-8dbb-d75f30491323

📥 Commits

Reviewing files that changed from the base of the PR and between ba95f5b and 34ddfbc.

📒 Files selected for processing (1)
  • uninstall.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • uninstall.php

Walkthrough

Adds a new uninstall settings UI to admin settings, a Tools admin page with form import/export and maintenance actions, and an uninstall script that conditionally deletes plugin tables, posts/pages, and options based on the stored uninstall settings.

Changes

Cohort / File(s) Summary
Uninstall Settings
admin/class-admin-settings.php
Adds private $uninstall_settings and registration/rendering/sanitization for an Uninstall Settings section with four yes/no toggles (delete_settings, delete_database, delete_forms, delete_pages) and corresponding markup callbacks.
Tools & Import/Export
admin/class-tools.php
Adds admin tools for listing/exporting/importing forms and registration forms, JSON import/export helpers (import_json_file, export_to_json), metadata formatting, UI/nonce handling, and a tools page with maintenance actions and status messaging.
Uninstall Handler
uninstall.php
Adds WPUF_Uninstaller that reads wpuf_uninstall options and conditionally drops plugin tables, deletes WPUF posts/forms, removes pages with WPUF shortcodes, and deletes stored options; always removes the wpuf_uninstall option and flushes cache.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 I hopped through code and found a plan,
Toggles for tidy, tools to scan,
Exports packed in JSON light,
Uninstall clears what you indict,
Hop, click — the plugin sleeps at night.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix/add data removing option' is vague and generic, using non-descriptive terms that don't clearly convey what the changeset accomplishes. Revise to a more specific title such as 'Add uninstall settings section with data removal options' to clearly describe the main feature being added.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 91.30% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
admin/class-tools.php (3)

210-223: Use elseif instead of else if.

WordPress coding standards prefer elseif over else if.

🧹 Proposed fix
     public function export_forms( $form_type, $export_type, $form_ids ) {
         if ( $export_type === 'all' ) {
             static::export_to_json( $form_type );
-        } else if ( $export_type === 'selected' ) {
+        } elseif ( $export_type === 'selected' ) {
             if ( empty( $form_ids ) ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admin/class-tools.php` around lines 210 - 223, In the export_forms method,
replace the "else if" conditional with the WordPress-preferred "elseif" form to
conform to coding standards; locate the function export_forms and change the
"else if ( $export_type === 'selected' )" to "elseif ( $export_type ===
'selected' )" (keeping the same block logic and calls to static::export_to_json
and the empty($form_ids) check) so only the conditional syntax is updated.

287-295: WPCS style violations in formetted_meta_key_value().

Multiple coding standard issues:

  1. Reserved keyword array as parameter name
  2. Extra space in empty array declaration
  3. Missing spaces around array key

Also note: method name has a typo — "formetted" should be "formatted".

🧹 Proposed fixes
-    public function formetted_meta_key_value( $array ) {
-        $result = [ ];
+    public function formatted_meta_key_value( $data ) {
+        $result = [];

         foreach ( $array as $key => $val ) {
-            $result[$key] = $val[0];
+            $result[ $key ] = $val[0];
         }

         return $result;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admin/class-tools.php` around lines 287 - 295, Rename the method
formetted_meta_key_value to formatted_meta_key_value, change the parameter from
the reserved name $array to something like $meta (or $items), normalize the
empty array declaration to $result = []; and apply WPCS spacing for array
keys/indices (e.g. $result[ $key ] = $val[0];). Update any callers of
formetted_meta_key_value to the new method name and new parameter name as
needed.

231-278: Multiple WPCS violations and potential timezone issues.

Several issues flagged by the pipeline:

  1. Line 235: date() should be gmdate() to avoid timezone issues
  2. Line 238, 247: Missing space after !
  3. Line 268: json_encode() should be wp_json_encode()
♻️ Proposed fixes
     public static function export_to_json( $post_type, $post_ids = [] ) {
         $formatted_data = [];
         $ids            = [];
         $blogname       = strtolower( str_replace( ' ', '-', get_option( 'blogname' ) ) );
-        $date           = date( 'Y-m-d' );
+        $date           = gmdate( 'Y-m-d' );
         $json_name      = $blogname . '-wpuf-' . $post_type . '-' . $date; // Namming the filename will be generated.

-        if ( !empty( $post_ids ) ) {
+        if ( ! empty( $post_ids ) ) {
             foreach ( $post_ids as $key => $value ) {
                 array_push( $ids, $value );
             }
         }

         $args = [
             'post_status' => 'publish',
             'post_type'   => $post_type,
-            'post__in'    => ( !empty( $ids ) ) ? $ids : '',
+            'post__in'    => ( ! empty( $ids ) ) ? $ids : '',
         ];

         // ... existing code ...

-        $json_file = json_encode( $formatted_data ); // Encode data into json data
+        $json_file = wp_json_encode( $formatted_data ); // Encode data into json data
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admin/class-tools.php` around lines 231 - 278, Change date() to gmdate() when
building $date in export_to_json to avoid timezone issues (update the $date
assignment in export_to_json), ensure there is a space after the negation
operator in conditionals like if ( ! empty( $post_ids ) ) and the ternary for
'post__in' (use ! empty( $ids ) ), and replace json_encode( $formatted_data )
with wp_json_encode( $formatted_data ) when assigning $json_file; these edits
are all inside the export_to_json method and reference $date, the if ( ! empty(
$post_ids ) ) check, the 'post__in' => ( ! empty( $ids ) ) ? $ids : ''
expression, and the $json_file = ... line.
uninstall.php (2)

54-73: Remove unused get_all_page_ids() method.

This private method is never called. Page deletion on line 33 uses direct SQL instead. Remove dead code to improve maintainability.

♻️ Proposed fix
-    /**
-     * Delete all WordPress page ids as an array
-     *
-     * `@since` WPUF
-     *
-     * `@return` void
-     */
-    private function get_all_page_ids( $post_type = 'page' ) {
-        $page_ids = [];
-        $pages = get_posts(
-            [
-                'post_type'              => $post_type,
-                'numberposts'            => - 1,
-                'no_found_rows'          => true,
-                'update_post_meta_cache' => false,
-                'update_post_term_cache' => false,
-            ]
-        );
-
-        if ( $pages ) {
-            foreach ( $pages as $page ) {
-                $page_ids[] = $page->ID;
-            }
-        }
-
-        return $page_ids;
-    }
-
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uninstall.php` around lines 54 - 73, Remove the dead private method
get_all_page_ids( $post_type = 'page' ) and its entire body from uninstall.php
because page deletion is handled elsewhere via direct SQL; search the codebase
for any references to get_all_page_ids and remove or update them if found to
avoid undefined calls, then run tests/lint to confirm no usages remain.

134-141: Non-existent tables in get_tables() list.

Per includes/Installer.php, only wpuf_transaction and wpuf_subscribers tables are created. The wpuf_message and wpuf_activity tables don't exist in the codebase. While DROP TABLE IF EXISTS handles this gracefully, you should remove references to non-existent tables to avoid confusion.

🧹 Proposed cleanup
 private function get_tables() {
     return [
         'wpuf_transaction',
         'wpuf_subscribers',
-        'wpuf_message',
-        'wpuf_activity',
     ];
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uninstall.php` around lines 134 - 141, The get_tables() method currently
lists non-existent tables (wpuf_message, wpuf_activity); update the get_tables()
function to only return the actual created tables (wpuf_transaction and
wpuf_subscribers) as defined in includes/Installer.php, removing wpuf_message
and wpuf_activity to avoid confusion.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@admin/class-tools.php`:
- Around line 129-132: The sprintf() call in the else branch is creating a
string but discarding it (same bug as in list_forms); update the else branch so
the message is actually output—either replace sprintf() with printf() or wrap it
with echo (e.g., echo sprintf(...)) so the '<p>Sorry you have no form to
export</p>' is rendered; locate the sprintf call in class-tools.php and modify
it accordingly.
- Around line 115-119: Remove the stray literal '";' after the PHP echo in the
option element inside the foreach loop; locate the foreach ( $forms as $form )
block and the line that renders <option value="<?php echo esc_attr( $form->ID );
?>"><?php echo esc_attr( $form->post_title ); ?></option>"; and delete the
trailing '";' so only the option markup and PHP echo remain.
- Around line 270-277: The header() calls are sent after echoing $json_file
which can trigger "headers already sent" warnings; move the header(
'Content-Type: ...' ) and header( "Content-Disposition: attachment;
filename=$json_name.json" ) lines to before the echo $json_file (keep ob_clean()
before the headers if you want to clear buffers), ensure $json_name is safely
escaped for the filename, then echo $json_file and exit(); so headers are always
sent prior to any output.
- Around line 65-67: The sprintf() call in the else branch is returning a string
that is never output, so users never see the "no forms" message; update the else
branch in admin/class-tools.php (the block containing sprintf( '<p>%s</p>', __(
'Sorry you have no form to export', 'wp-user-frontend' ) );) to actually output
the string—e.g., use echo sprintf(...) or replace with printf(...) (and ensure
proper escaping if needed) so the message is rendered to the user.

In `@uninstall.php`:
- Around line 32-34: The DELETE query under the
uninstall_settings['delete_pages'] check only matches post_content that starts
with the shortcode; update the SQL in the $wpdb->query call that targets
{$wpdb->posts} (the DELETE WHERE post_type = 'page' AND post_content LIKE ...)
to use a contains pattern (change LIKE '[wpuf%' to LIKE '%[wpuf%') so pages that
contain WPUF shortcodes anywhere in the content are matched; verify this change
in the uninstall_settings / delete_pages flow to ensure it aligns with the
intended deletion policy.
- Around line 36-38: The current DELETE uses a substring pattern "%wpuf_%" which
matches anywhere; change it to a prefix match so only options that start with
the wpuf_ prefix are removed: update the $wpdb->query call that references
$wpdb->options and option_name to use a LIKE pattern that matches from the start
(e.g., "wpuf\_%" with an appropriate SQL ESCAPE or escaped backslash in the PHP
string) instead of "%wpuf_%", ensuring you still target only options beginning
with the wpuf_ prefix when checking uninstall_settings['delete_settings'].

---

Nitpick comments:
In `@admin/class-tools.php`:
- Around line 210-223: In the export_forms method, replace the "else if"
conditional with the WordPress-preferred "elseif" form to conform to coding
standards; locate the function export_forms and change the "else if (
$export_type === 'selected' )" to "elseif ( $export_type === 'selected' )"
(keeping the same block logic and calls to static::export_to_json and the
empty($form_ids) check) so only the conditional syntax is updated.
- Around line 287-295: Rename the method formetted_meta_key_value to
formatted_meta_key_value, change the parameter from the reserved name $array to
something like $meta (or $items), normalize the empty array declaration to
$result = []; and apply WPCS spacing for array keys/indices (e.g. $result[ $key
] = $val[0];). Update any callers of formetted_meta_key_value to the new method
name and new parameter name as needed.
- Around line 231-278: Change date() to gmdate() when building $date in
export_to_json to avoid timezone issues (update the $date assignment in
export_to_json), ensure there is a space after the negation operator in
conditionals like if ( ! empty( $post_ids ) ) and the ternary for 'post__in'
(use ! empty( $ids ) ), and replace json_encode( $formatted_data ) with
wp_json_encode( $formatted_data ) when assigning $json_file; these edits are all
inside the export_to_json method and reference $date, the if ( ! empty(
$post_ids ) ) check, the 'post__in' => ( ! empty( $ids ) ) ? $ids : ''
expression, and the $json_file = ... line.

In `@uninstall.php`:
- Around line 54-73: Remove the dead private method get_all_page_ids( $post_type
= 'page' ) and its entire body from uninstall.php because page deletion is
handled elsewhere via direct SQL; search the codebase for any references to
get_all_page_ids and remove or update them if found to avoid undefined calls,
then run tests/lint to confirm no usages remain.
- Around line 134-141: The get_tables() method currently lists non-existent
tables (wpuf_message, wpuf_activity); update the get_tables() function to only
return the actual created tables (wpuf_transaction and wpuf_subscribers) as
defined in includes/Installer.php, removing wpuf_message and wpuf_activity to
avoid confusion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cc2f1c19-d9ce-4022-8add-4898aca215d4

📥 Commits

Reviewing files that changed from the base of the PR and between 5f313fa and ba95f5b.

📒 Files selected for processing (3)
  • admin/class-admin-settings.php
  • admin/class-tools.php
  • uninstall.php

Comment on lines +65 to +67
} else {
sprintf( '<p>%s</p>', __( 'Sorry you have no form to export', 'wp-user-frontend' ) );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bug: sprintf() output is discarded.

The sprintf() return value is not echoed, so the "no forms" message is never displayed to users.

🐛 Proposed fix
         <?php
     } else {
-        sprintf( '<p>%s</p>', __( 'Sorry you have no form to export', 'wp-user-frontend' ) );
+        printf( '<p>%s</p>', esc_html__( 'Sorry you have no form to export', 'wp-user-frontend' ) );
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admin/class-tools.php` around lines 65 - 67, The sprintf() call in the else
branch is returning a string that is never output, so users never see the "no
forms" message; update the else branch in admin/class-tools.php (the block
containing sprintf( '<p>%s</p>', __( 'Sorry you have no form to export',
'wp-user-frontend' ) );) to actually output the string—e.g., use echo
sprintf(...) or replace with printf(...) (and ensure proper escaping if needed)
so the message is rendered to the user.

Comment on lines +115 to +119
<select class="formlist" name="form_ids[]" multiple="multiple">
<?php foreach ( $forms as $form ) { ?>
<option value="<?php echo esc_attr( $form->ID ); ?>"><?php echo esc_attr( $form->post_title ); ?></option>";
<?php } ?>
</select>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

HTML syntax error: stray "; will be rendered in output.

Line 117 has extra "; after the closing PHP tag that will appear as literal text in the select dropdown.

🐛 Proposed fix
                     <select class="formlist" name="form_ids[]" multiple="multiple">
                         <?php foreach ( $forms as $form ) { ?>
-                            <option value="<?php echo esc_attr( $form->ID ); ?>"><?php echo esc_attr( $form->post_title ); ?></option>";
+                            <option value="<?php echo esc_attr( $form->ID ); ?>"><?php echo esc_attr( $form->post_title ); ?></option>
                         <?php } ?>
                     </select>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<select class="formlist" name="form_ids[]" multiple="multiple">
<?php foreach ( $forms as $form ) { ?>
<option value="<?php echo esc_attr( $form->ID ); ?>"><?php echo esc_attr( $form->post_title ); ?></option>";
<?php } ?>
</select>
<select class="formlist" name="form_ids[]" multiple="multiple">
<?php foreach ( $forms as $form ) { ?>
<option value="<?php echo esc_attr( $form->ID ); ?>"><?php echo esc_attr( $form->post_title ); ?></option>
<?php } ?>
</select>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admin/class-tools.php` around lines 115 - 119, Remove the stray literal '";'
after the PHP echo in the option element inside the foreach loop; locate the
foreach ( $forms as $form ) block and the line that renders <option value="<?php
echo esc_attr( $form->ID ); ?>"><?php echo esc_attr( $form->post_title );
?></option>"; and delete the trailing '";' so only the option markup and PHP
echo remain.

Comment on lines +129 to +132
<?php
} else {
sprintf( '<p>%s</p>', __( 'Sorry you have no form to export', 'wp-user-frontend' ) );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Bug: sprintf() output is discarded (same as list_forms).

🐛 Proposed fix
     } else {
-        sprintf( '<p>%s</p>', __( 'Sorry you have no form to export', 'wp-user-frontend' ) );
+        printf( '<p>%s</p>', esc_html__( 'Sorry you have no form to export', 'wp-user-frontend' ) );
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<?php
} else {
sprintf( '<p>%s</p>', __( 'Sorry you have no form to export', 'wp-user-frontend' ) );
}
<?php
} else {
printf( '<p>%s</p>', esc_html__( 'Sorry you have no form to export', 'wp-user-frontend' ) );
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admin/class-tools.php` around lines 129 - 132, The sprintf() call in the else
branch is creating a string but discarding it (same bug as in list_forms);
update the else branch so the message is actually output—either replace
sprintf() with printf() or wrap it with echo (e.g., echo sprintf(...)) so the
'<p>Sorry you have no form to export</p>' is rendered; locate the sprintf call
in class-tools.php and modify it accordingly.

Comment on lines +270 to +277
ob_clean();

echo $json_file; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped

header( 'Content-Type: text/json; charset=' . get_option( 'blog_charset' ) );
header( "Content-Disposition: attachment; filename=$json_name.json" );

exit();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Send headers before output to prevent "headers already sent" errors.

The header() calls on lines 274-275 occur after echo on line 272. This will cause a PHP warning if output buffering is disabled, and potentially corrupt the downloaded file.

🐛 Proposed fix — move headers before output
         $json_file = wp_json_encode( $formatted_data );

         ob_clean();

+        header( 'Content-Type: text/json; charset=' . get_option( 'blog_charset' ) );
+        header( "Content-Disposition: attachment; filename=$json_name.json" );
+
         echo $json_file; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped

-        header( 'Content-Type: text/json; charset=' . get_option( 'blog_charset' ) );
-        header( "Content-Disposition: attachment; filename=$json_name.json" );
-
         exit();
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ob_clean();
echo $json_file; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
header( 'Content-Type: text/json; charset=' . get_option( 'blog_charset' ) );
header( "Content-Disposition: attachment; filename=$json_name.json" );
exit();
ob_clean();
header( 'Content-Type: text/json; charset=' . get_option( 'blog_charset' ) );
header( "Content-Disposition: attachment; filename=$json_name.json" );
echo $json_file; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
exit();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@admin/class-tools.php` around lines 270 - 277, The header() calls are sent
after echoing $json_file which can trigger "headers already sent" warnings; move
the header( 'Content-Type: ...' ) and header( "Content-Disposition: attachment;
filename=$json_name.json" ) lines to before the echo $json_file (keep ob_clean()
before the headers if you want to clear buffers), ensure $json_name is safely
escaped for the filename, then echo $json_file and exit(); so headers are always
sent prior to any output.

Comment on lines +36 to +38
if ( ! empty( $uninstall_settings['delete_settings'] ) ) {
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '%wpuf_%'" );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for all option names used by this plugin to verify naming conventions
rg -n "get_option\s*\(\s*['\"]" --type php | grep -i wpuf | head -30
rg -n "update_option\s*\(\s*['\"]" --type php | grep -i wpuf | head -30
rg -n "delete_option\s*\(\s*['\"]" --type php | grep -i wpuf | head -30

Repository: weDevsOfficial/wp-user-frontend

Length of output: 7647


🏁 Script executed:

cat -n uninstall.php

Repository: weDevsOfficial/wp-user-frontend

Length of output: 4610


Use prefix matching instead of substring matching for better precision.

The pattern '%wpuf_%' is unnecessarily broad. Since all WPUF options use the wpuf_ prefix consistently, use a more precise prefix match:

Suggested change
 if ( ! empty( $uninstall_settings['delete_settings'] ) ) {
-    $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '%wpuf_%'" );
+    $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'wpuf_%'" );
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ( ! empty( $uninstall_settings['delete_settings'] ) ) {
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '%wpuf_%'" );
}
if ( ! empty( $uninstall_settings['delete_settings'] ) ) {
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'wpuf_%'" );
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@uninstall.php` around lines 36 - 38, The current DELETE uses a substring
pattern "%wpuf_%" which matches anywhere; change it to a prefix match so only
options that start with the wpuf_ prefix are removed: update the $wpdb->query
call that references $wpdb->options and option_name to use a LIKE pattern that
matches from the start (e.g., "wpuf\_%" with an appropriate SQL ESCAPE or
escaped backslash in the PHP string) instead of "%wpuf_%", ensuring you still
target only options beginning with the wpuf_ prefix when checking
uninstall_settings['delete_settings'].

Replace direct DB deletion of pages with a new delete_pages() method that selects pages containing WPUF shortcodes and removes them via wp_delete_post() to ensure proper cleanup. Remove the old get_all_page_ids helper and tidy up uninstall flows (normalize WP_Query args, remove extra blank lines). Keep existing settings, options cleanup, and table drops intact; maintain postmeta cleanup after form deletions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants