Changeset 3434009
- Timestamp:
- 01/07/2026 02:08:39 AM (3 months ago)
- Location:
- nhrrob-options-table-manager
- Files:
-
- 14 edited
- 1 copied
-
tags/1.1.9 (copied) (copied from nhrrob-options-table-manager/trunk)
-
tags/1.1.9/assets/css/admin.css (modified) (1 diff)
-
tags/1.1.9/assets/js/admin.js (modified) (5 diffs)
-
tags/1.1.9/includes/Ajax/AjaxHandler.php (modified) (2 diffs)
-
tags/1.1.9/includes/Managers/OptionsTableManager.php (modified) (4 diffs)
-
tags/1.1.9/includes/views/admin/settings/index.php (modified) (3 diffs)
-
tags/1.1.9/nhrrob-options-table-manager.php (modified) (2 diffs)
-
tags/1.1.9/readme.txt (modified) (3 diffs)
-
trunk/assets/css/admin.css (modified) (1 diff)
-
trunk/assets/js/admin.js (modified) (5 diffs)
-
trunk/includes/Ajax/AjaxHandler.php (modified) (2 diffs)
-
trunk/includes/Managers/OptionsTableManager.php (modified) (4 diffs)
-
trunk/includes/views/admin/settings/index.php (modified) (3 diffs)
-
trunk/nhrrob-options-table-manager.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
nhrrob-options-table-manager/tags/1.1.9/assets/css/admin.css
r3263431 r3434009 427 427 border: none; 428 428 } 429 430 .nhrotm-filter-group.nhrotm-bulk-action-group { 431 position: absolute; 432 left: 10px; 433 } 434 435 #nhrotm-bulk-action-selector { 436 min-width: 160px; 437 padding: 4px 8px; 438 border: 1px solid #ddd; 439 border-radius: 4px; 440 } 441 442 #nhrotm-do-bulk-action { 443 width: 60px; 444 padding: 4px 8px; 445 color: #000; 446 border: 1px solid #ddd; 447 border-radius: 4px; 448 } 449 450 tfoot td.manage-column.column-cb.check-column { 451 padding: 8px 10px; 452 } -
nhrrob-options-table-manager/tags/1.1.9/assets/js/admin.js
r3263431 r3434009 40 40 "data": function(d) { 41 41 // Add column search values to the request 42 for (let i = 0; i < d.columns.length; i++) { 43 d.columns[i].search.value = $('#nhrotm-data-table tfoot input').eq(i).val(); 42 // Remap inputs because Col 0 (checkbox) and Col 5 (Actions) have no inputs 43 // Inputs are present for Col 1, 2, 3, 4 44 d.columns[0].search.value = ''; // Checkbox 45 if ($('#nhrotm-data-table tfoot input').length >= 4) { 46 d.columns[1].search.value = $('#nhrotm-data-table tfoot input').eq(0).val(); 47 d.columns[2].search.value = $('#nhrotm-data-table tfoot input').eq(1).val(); 48 d.columns[3].search.value = $('#nhrotm-data-table tfoot input').eq(2).val(); 49 d.columns[4].search.value = $('#nhrotm-data-table tfoot input').eq(3).val(); 50 d.columns[5].search.value = ''; 44 51 } 45 52 … … 51 58 $('#delete-expired-transients').attr('disabled', false); 52 59 53 let currentSearch = d.columns[1].search.value || ''; 60 // option_name is now at index 2 (0=cb, 1=id, 2=name) 61 let currentSearch = d.columns[2].search.value || ''; 54 62 if (!currentSearch.includes('transient_')) { 55 d.columns[ 1].search.value = 'transient_' + currentSearch;63 d.columns[2].search.value = 'transient_' + currentSearch; 56 64 } 57 65 } … … 59 67 }, 60 68 "columns": [ 69 { 70 "data": null, 71 "orderable": false, 72 "visible": true, 73 "searchable": false, 74 "render": function(data, type, row) { 75 return '<input type="checkbox" class="nhrotm-checkbox" value="' + row.option_name + '">'; 76 } 77 }, 61 78 { "data": "option_id" }, 62 79 { "data": "option_name" }, … … 69 86 // "scrollCollapse": true, 70 87 // "paging": true, 71 // "order": [[0, 'asc']], // Default order on the first column in ascending,88 "order": [[1, 'asc']], // Default order on the first column in ascending, 72 89 "initComplete": function () { 73 90 this.api() 74 91 .columns() 75 .every(function () { 92 .every(function (index) { 93 // Skip checkbox column (index 0) and Actions column (index 5) 94 if (index === 0 || index === 5) return; 95 76 96 let column = this; 77 97 let title = column.footer().textContent; … … 638 658 }); 639 659 660 // Select All handler 661 $('#nhrotm-select-all, #nhrotm-select-all-footer').on('click', function() { 662 var rows = $('#nhrotm-data-table').DataTable().rows({ 'search': 'applied' }).nodes(); 663 $('input[type="checkbox"]', rows).prop('checked', this.checked); 664 $('#nhrotm-select-all, #nhrotm-select-all-footer').prop('checked', this.checked); 665 }); 666 667 // Handle individual checkbox click to update Select All state 668 $('#nhrotm-data-table tbody').on('change', 'input[type="checkbox"]', function(){ 669 if(!this.checked){ 670 var el = $('#nhrotm-select-all, #nhrotm-select-all-footer').get(0); 671 if(el && el.checked && ('indeterminate' in el)){ 672 el.indeterminate = true; 673 } 674 } 675 }); 676 677 // Bulk Actions 678 $('#nhrotm-do-bulk-action').on('click', function(e) { 679 e.preventDefault(); 680 const action = $('#nhrotm-bulk-action-selector').val(); 681 682 if (action === '-1') { 683 showToast("Please select an action.", "error"); 684 return; 685 } 686 687 const selectedOptions = []; 688 $('#nhrotm-data-table tbody input.nhrotm-checkbox:checked').each(function() { 689 selectedOptions.push($(this).val()); 690 }); 691 692 if (selectedOptions.length === 0) { 693 showToast("Please select at least one option.", "warning"); 694 return; 695 } 696 697 if (action === 'delete') { 698 if (confirm("Are you sure you want to delete selected options?")) { 699 bulkDeleteOptions(selectedOptions); 700 } 701 } 702 }); 703 704 function bulkDeleteOptions(optionNames) { 705 $.ajax({ 706 url: nhrotmOptionsTableManager.ajaxUrl, 707 method: "POST", 708 data: { 709 action: "nhrotm_bulk_delete_options", 710 nonce: nhrotmOptionsTableManager.nonce, 711 option_names: optionNames 712 }, 713 success: function(response) { 714 if (response.success) { 715 showToast("Options deleted successfully!", "success"); 716 table.ajax.reload(null, false); 717 $('#nhrotm-select-all, #nhrotm-select-all-footer').prop('checked', false); 718 } else { 719 showToast("Failed to delete options.", "error"); 720 } 721 } 722 }); 723 } 724 640 725 }); 641 726 })(jQuery); -
nhrrob-options-table-manager/tags/1.1.9/includes/Ajax/AjaxHandler.php
r3263431 r3434009 33 33 'nhrotm_edit_option' => 'edit_option', 34 34 'nhrotm_delete_option' => 'delete_option', 35 'nhrotm_bulk_delete_options' => 'bulk_delete_options', 35 36 'nhrotm_delete_expired_transients' => 'delete_expired_transients', 36 37 'nhrotm_option_usage_analytics' => 'option_usage_analytics', … … 109 110 } 110 111 } 112 113 public function bulk_delete_options() { 114 try { 115 $result = $this->options_manager->bulk_delete_records(); 116 if ( $result ) { 117 wp_send_json_success('Options deleted successfully!'); 118 } else { 119 wp_send_json_error('Failed to delete options!'); 120 } 121 } catch (\Exception $e) { 122 wp_send_json_error($e->getMessage()); 123 } 124 } 111 125 112 126 public function delete_expired_transients() { -
nhrrob-options-table-manager/tags/1.1.9/includes/Managers/OptionsTableManager.php
r3263180 r3434009 43 43 // Ensure order column is valid using whitelist approach 44 44 if ($order_column_index < 0 || $order_column_index >= count($columns)) { 45 $order_column_index = 0; // Default to first column45 $order_column_index = 1; // Default to 'option_id' (index 1) 46 46 } 47 47 $order_column = $columns[$order_column_index]; 48 49 if (empty($order_column)) { 50 $order_column = 'option_id'; 51 } 48 52 49 53 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching … … 83 87 // Individual column searches 84 88 if (!empty($column_search)) { 85 // option_id column (index 0) 86 if (!empty($column_search[0])) { 89 // checkbox column (index 0) - Ignore/Not searchable via specific field in this implementation 90 91 // option_id column (index 1) 92 if (!empty($column_search[1])) { 87 93 // For numeric column, use exact match or range 88 if (is_numeric($column_search[ 0])) {89 $where_clauses[] = $this->wpdb->prepare("option_id = %d", intval($column_search[ 0]));90 } 91 } 92 93 // option_name column (index 1)94 if (!empty($column_search[ 1])) {94 if (is_numeric($column_search[1])) { 95 $where_clauses[] = $this->wpdb->prepare("option_id = %d", intval($column_search[1])); 96 } 97 } 98 99 // option_name column (index 2) 100 if (!empty($column_search[2])) { 95 101 $where_clauses[] = $this->wpdb->prepare( 96 102 "option_name LIKE %s", 97 '%' . $this->wpdb->esc_like($column_search[ 1]) . '%'103 '%' . $this->wpdb->esc_like($column_search[2]) . '%' 98 104 ); 99 105 } 100 106 101 // option_value column (index 2)102 if (!empty($column_search[ 2])) {107 // option_value column (index 3) 108 if (!empty($column_search[3])) { 103 109 $where_clauses[] = $this->wpdb->prepare( 104 110 "option_value LIKE %s", 105 '%' . $this->wpdb->esc_like($column_search[ 2]) . '%'111 '%' . $this->wpdb->esc_like($column_search[3]) . '%' 106 112 ); 107 113 } 108 114 109 // autoload column (index 3)110 if (!empty($column_search[ 3])) {115 // autoload column (index 4) 116 if (!empty($column_search[4])) { 111 117 $where_clauses[] = $this->wpdb->prepare( 112 118 "autoload LIKE %s", 113 '%' . $this->wpdb->esc_like($column_search[ 3]) . '%'119 '%' . $this->wpdb->esc_like($column_search[4]) . '%' 114 120 ); 115 121 } … … 335 341 336 342 /** 343 * Bulk delete options 344 * 345 * @return bool Success status 346 */ 347 public function bulk_delete_records() { 348 // Verify nonce 349 if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'nhrotm-admin-nonce')) { 350 throw new \Exception('Invalid nonce'); 351 } 352 353 $this->validate_permissions(); 354 355 $option_names = isset($_POST['option_names']) ? (array) $_POST['option_names'] : []; 356 357 if (empty($option_names)) { 358 throw new \Exception('No options selected'); 359 } 360 361 foreach ($option_names as $option_name) { 362 $option_name = sanitize_text_field(wp_unslash($option_name)); 363 364 if ($this->is_protected_item($option_name)) { 365 continue; // Skip protected items 366 } 367 368 delete_option($option_name); 369 } 370 371 return true; 372 } 373 374 /** 337 375 * Delete an expired transient 338 376 * … … 444 482 */ 445 483 protected function get_searchable_columns() { 446 return [ 'option_id', 'option_name', 'option_value', 'autoload'];484 return [null, 'option_id', 'option_name', 'option_value', 'autoload']; 447 485 } 448 486 } -
nhrrob-options-table-manager/tags/1.1.9/includes/views/admin/settings/index.php
r3263431 r3434009 28 28 <div class="nhrotm-filter-container"> 29 29 <div class="nhrotm-filter-row"> 30 <div class="nhrotm-filter-group nhrotm-bulk-action-group"> 31 <select id="nhrotm-bulk-action-selector"> 32 <option value="-1"><?php esc_html_e('Bulk Actions', 'nhrrob-options-table-manager'); ?></option> 33 <option value="delete"><?php esc_html_e('Delete', 'nhrrob-options-table-manager'); ?></option> 34 </select> 35 <button id="nhrotm-do-bulk-action" class="button action"><?php esc_html_e('Apply', 'nhrrob-options-table-manager'); ?></button> 36 </div> 37 30 38 <div class="nhrotm-filter-group"> 31 39 <select id="option-type-filter"> … … 40 48 </div> 41 49 <!-- Filter ends --> 42 50 43 51 <table id="nhrotm-data-table" class="nhrotm-data-table wp-list-table widefat fixed striped"> 44 52 <thead> 45 53 <tr> 54 <td id="cb" class="manage-column column-cb check-column"><input type="checkbox" id="nhrotm-select-all"></td> 46 55 <th><?php esc_html_e('Option ID', 'nhrrob-options-table-manager'); ?></th> 47 56 <th><?php esc_html_e('Option Name', 'nhrrob-options-table-manager'); ?></th> … … 54 63 <tfoot> 55 64 <tr> 65 <td class="manage-column column-cb check-column"><input type="checkbox" id="nhrotm-select-all-footer"></td> 56 66 <th><?php esc_html_e('Option ID', 'nhrrob-options-table-manager'); ?></th> 57 67 <th><?php esc_html_e('Option Name', 'nhrrob-options-table-manager'); ?></th> -
nhrrob-options-table-manager/tags/1.1.9/nhrrob-options-table-manager.php
r3405973 r3434009 6 6 * Author: Nazmul Hasan Robin 7 7 * Author URI: https://profiles.wordpress.org/nhrrob/ 8 * Version: 1.1. 88 * Version: 1.1.9 9 9 * Requires at least: 6.0 10 10 * Requires PHP: 7.4 … … 28 28 * @var string 29 29 */ 30 const nhrotm_version = '1.1. 8';30 const nhrotm_version = '1.1.9'; 31 31 32 32 /** -
nhrrob-options-table-manager/tags/1.1.9/readme.txt
r3405973 r3434009 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1.1. 87 Stable tag: 1.1.9 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 38 38 We're constantly improving NHR Options Table Manager! Here's what's on the way: 39 39 - **Bulk Deletion** – Quickly remove multiple options and user meta entries at once. 40 - **WP Recipe Maker Table Support** – Manage recipe-related data efficiently.41 - **Expired Transient Deletion** – Automatically clean up expired transients to free up database space.42 40 - **More Exciting Features** – Stay tuned for additional enhancements! 43 41 … … 85 83 86 84 == Changelog == 85 86 = 1.1.9 - 05/01/2026 = 87 - Added: Bulk delete options feature 87 88 88 89 = 1.1.8 - 30/11/2025 = -
nhrrob-options-table-manager/trunk/assets/css/admin.css
r3263431 r3434009 427 427 border: none; 428 428 } 429 430 .nhrotm-filter-group.nhrotm-bulk-action-group { 431 position: absolute; 432 left: 10px; 433 } 434 435 #nhrotm-bulk-action-selector { 436 min-width: 160px; 437 padding: 4px 8px; 438 border: 1px solid #ddd; 439 border-radius: 4px; 440 } 441 442 #nhrotm-do-bulk-action { 443 width: 60px; 444 padding: 4px 8px; 445 color: #000; 446 border: 1px solid #ddd; 447 border-radius: 4px; 448 } 449 450 tfoot td.manage-column.column-cb.check-column { 451 padding: 8px 10px; 452 } -
nhrrob-options-table-manager/trunk/assets/js/admin.js
r3263431 r3434009 40 40 "data": function(d) { 41 41 // Add column search values to the request 42 for (let i = 0; i < d.columns.length; i++) { 43 d.columns[i].search.value = $('#nhrotm-data-table tfoot input').eq(i).val(); 42 // Remap inputs because Col 0 (checkbox) and Col 5 (Actions) have no inputs 43 // Inputs are present for Col 1, 2, 3, 4 44 d.columns[0].search.value = ''; // Checkbox 45 if ($('#nhrotm-data-table tfoot input').length >= 4) { 46 d.columns[1].search.value = $('#nhrotm-data-table tfoot input').eq(0).val(); 47 d.columns[2].search.value = $('#nhrotm-data-table tfoot input').eq(1).val(); 48 d.columns[3].search.value = $('#nhrotm-data-table tfoot input').eq(2).val(); 49 d.columns[4].search.value = $('#nhrotm-data-table tfoot input').eq(3).val(); 50 d.columns[5].search.value = ''; 44 51 } 45 52 … … 51 58 $('#delete-expired-transients').attr('disabled', false); 52 59 53 let currentSearch = d.columns[1].search.value || ''; 60 // option_name is now at index 2 (0=cb, 1=id, 2=name) 61 let currentSearch = d.columns[2].search.value || ''; 54 62 if (!currentSearch.includes('transient_')) { 55 d.columns[ 1].search.value = 'transient_' + currentSearch;63 d.columns[2].search.value = 'transient_' + currentSearch; 56 64 } 57 65 } … … 59 67 }, 60 68 "columns": [ 69 { 70 "data": null, 71 "orderable": false, 72 "visible": true, 73 "searchable": false, 74 "render": function(data, type, row) { 75 return '<input type="checkbox" class="nhrotm-checkbox" value="' + row.option_name + '">'; 76 } 77 }, 61 78 { "data": "option_id" }, 62 79 { "data": "option_name" }, … … 69 86 // "scrollCollapse": true, 70 87 // "paging": true, 71 // "order": [[0, 'asc']], // Default order on the first column in ascending,88 "order": [[1, 'asc']], // Default order on the first column in ascending, 72 89 "initComplete": function () { 73 90 this.api() 74 91 .columns() 75 .every(function () { 92 .every(function (index) { 93 // Skip checkbox column (index 0) and Actions column (index 5) 94 if (index === 0 || index === 5) return; 95 76 96 let column = this; 77 97 let title = column.footer().textContent; … … 638 658 }); 639 659 660 // Select All handler 661 $('#nhrotm-select-all, #nhrotm-select-all-footer').on('click', function() { 662 var rows = $('#nhrotm-data-table').DataTable().rows({ 'search': 'applied' }).nodes(); 663 $('input[type="checkbox"]', rows).prop('checked', this.checked); 664 $('#nhrotm-select-all, #nhrotm-select-all-footer').prop('checked', this.checked); 665 }); 666 667 // Handle individual checkbox click to update Select All state 668 $('#nhrotm-data-table tbody').on('change', 'input[type="checkbox"]', function(){ 669 if(!this.checked){ 670 var el = $('#nhrotm-select-all, #nhrotm-select-all-footer').get(0); 671 if(el && el.checked && ('indeterminate' in el)){ 672 el.indeterminate = true; 673 } 674 } 675 }); 676 677 // Bulk Actions 678 $('#nhrotm-do-bulk-action').on('click', function(e) { 679 e.preventDefault(); 680 const action = $('#nhrotm-bulk-action-selector').val(); 681 682 if (action === '-1') { 683 showToast("Please select an action.", "error"); 684 return; 685 } 686 687 const selectedOptions = []; 688 $('#nhrotm-data-table tbody input.nhrotm-checkbox:checked').each(function() { 689 selectedOptions.push($(this).val()); 690 }); 691 692 if (selectedOptions.length === 0) { 693 showToast("Please select at least one option.", "warning"); 694 return; 695 } 696 697 if (action === 'delete') { 698 if (confirm("Are you sure you want to delete selected options?")) { 699 bulkDeleteOptions(selectedOptions); 700 } 701 } 702 }); 703 704 function bulkDeleteOptions(optionNames) { 705 $.ajax({ 706 url: nhrotmOptionsTableManager.ajaxUrl, 707 method: "POST", 708 data: { 709 action: "nhrotm_bulk_delete_options", 710 nonce: nhrotmOptionsTableManager.nonce, 711 option_names: optionNames 712 }, 713 success: function(response) { 714 if (response.success) { 715 showToast("Options deleted successfully!", "success"); 716 table.ajax.reload(null, false); 717 $('#nhrotm-select-all, #nhrotm-select-all-footer').prop('checked', false); 718 } else { 719 showToast("Failed to delete options.", "error"); 720 } 721 } 722 }); 723 } 724 640 725 }); 641 726 })(jQuery); -
nhrrob-options-table-manager/trunk/includes/Ajax/AjaxHandler.php
r3263431 r3434009 33 33 'nhrotm_edit_option' => 'edit_option', 34 34 'nhrotm_delete_option' => 'delete_option', 35 'nhrotm_bulk_delete_options' => 'bulk_delete_options', 35 36 'nhrotm_delete_expired_transients' => 'delete_expired_transients', 36 37 'nhrotm_option_usage_analytics' => 'option_usage_analytics', … … 109 110 } 110 111 } 112 113 public function bulk_delete_options() { 114 try { 115 $result = $this->options_manager->bulk_delete_records(); 116 if ( $result ) { 117 wp_send_json_success('Options deleted successfully!'); 118 } else { 119 wp_send_json_error('Failed to delete options!'); 120 } 121 } catch (\Exception $e) { 122 wp_send_json_error($e->getMessage()); 123 } 124 } 111 125 112 126 public function delete_expired_transients() { -
nhrrob-options-table-manager/trunk/includes/Managers/OptionsTableManager.php
r3263180 r3434009 43 43 // Ensure order column is valid using whitelist approach 44 44 if ($order_column_index < 0 || $order_column_index >= count($columns)) { 45 $order_column_index = 0; // Default to first column45 $order_column_index = 1; // Default to 'option_id' (index 1) 46 46 } 47 47 $order_column = $columns[$order_column_index]; 48 49 if (empty($order_column)) { 50 $order_column = 'option_id'; 51 } 48 52 49 53 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching … … 83 87 // Individual column searches 84 88 if (!empty($column_search)) { 85 // option_id column (index 0) 86 if (!empty($column_search[0])) { 89 // checkbox column (index 0) - Ignore/Not searchable via specific field in this implementation 90 91 // option_id column (index 1) 92 if (!empty($column_search[1])) { 87 93 // For numeric column, use exact match or range 88 if (is_numeric($column_search[ 0])) {89 $where_clauses[] = $this->wpdb->prepare("option_id = %d", intval($column_search[ 0]));90 } 91 } 92 93 // option_name column (index 1)94 if (!empty($column_search[ 1])) {94 if (is_numeric($column_search[1])) { 95 $where_clauses[] = $this->wpdb->prepare("option_id = %d", intval($column_search[1])); 96 } 97 } 98 99 // option_name column (index 2) 100 if (!empty($column_search[2])) { 95 101 $where_clauses[] = $this->wpdb->prepare( 96 102 "option_name LIKE %s", 97 '%' . $this->wpdb->esc_like($column_search[ 1]) . '%'103 '%' . $this->wpdb->esc_like($column_search[2]) . '%' 98 104 ); 99 105 } 100 106 101 // option_value column (index 2)102 if (!empty($column_search[ 2])) {107 // option_value column (index 3) 108 if (!empty($column_search[3])) { 103 109 $where_clauses[] = $this->wpdb->prepare( 104 110 "option_value LIKE %s", 105 '%' . $this->wpdb->esc_like($column_search[ 2]) . '%'111 '%' . $this->wpdb->esc_like($column_search[3]) . '%' 106 112 ); 107 113 } 108 114 109 // autoload column (index 3)110 if (!empty($column_search[ 3])) {115 // autoload column (index 4) 116 if (!empty($column_search[4])) { 111 117 $where_clauses[] = $this->wpdb->prepare( 112 118 "autoload LIKE %s", 113 '%' . $this->wpdb->esc_like($column_search[ 3]) . '%'119 '%' . $this->wpdb->esc_like($column_search[4]) . '%' 114 120 ); 115 121 } … … 335 341 336 342 /** 343 * Bulk delete options 344 * 345 * @return bool Success status 346 */ 347 public function bulk_delete_records() { 348 // Verify nonce 349 if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'nhrotm-admin-nonce')) { 350 throw new \Exception('Invalid nonce'); 351 } 352 353 $this->validate_permissions(); 354 355 $option_names = isset($_POST['option_names']) ? (array) $_POST['option_names'] : []; 356 357 if (empty($option_names)) { 358 throw new \Exception('No options selected'); 359 } 360 361 foreach ($option_names as $option_name) { 362 $option_name = sanitize_text_field(wp_unslash($option_name)); 363 364 if ($this->is_protected_item($option_name)) { 365 continue; // Skip protected items 366 } 367 368 delete_option($option_name); 369 } 370 371 return true; 372 } 373 374 /** 337 375 * Delete an expired transient 338 376 * … … 444 482 */ 445 483 protected function get_searchable_columns() { 446 return [ 'option_id', 'option_name', 'option_value', 'autoload'];484 return [null, 'option_id', 'option_name', 'option_value', 'autoload']; 447 485 } 448 486 } -
nhrrob-options-table-manager/trunk/includes/views/admin/settings/index.php
r3263431 r3434009 28 28 <div class="nhrotm-filter-container"> 29 29 <div class="nhrotm-filter-row"> 30 <div class="nhrotm-filter-group nhrotm-bulk-action-group"> 31 <select id="nhrotm-bulk-action-selector"> 32 <option value="-1"><?php esc_html_e('Bulk Actions', 'nhrrob-options-table-manager'); ?></option> 33 <option value="delete"><?php esc_html_e('Delete', 'nhrrob-options-table-manager'); ?></option> 34 </select> 35 <button id="nhrotm-do-bulk-action" class="button action"><?php esc_html_e('Apply', 'nhrrob-options-table-manager'); ?></button> 36 </div> 37 30 38 <div class="nhrotm-filter-group"> 31 39 <select id="option-type-filter"> … … 40 48 </div> 41 49 <!-- Filter ends --> 42 50 43 51 <table id="nhrotm-data-table" class="nhrotm-data-table wp-list-table widefat fixed striped"> 44 52 <thead> 45 53 <tr> 54 <td id="cb" class="manage-column column-cb check-column"><input type="checkbox" id="nhrotm-select-all"></td> 46 55 <th><?php esc_html_e('Option ID', 'nhrrob-options-table-manager'); ?></th> 47 56 <th><?php esc_html_e('Option Name', 'nhrrob-options-table-manager'); ?></th> … … 54 63 <tfoot> 55 64 <tr> 65 <td class="manage-column column-cb check-column"><input type="checkbox" id="nhrotm-select-all-footer"></td> 56 66 <th><?php esc_html_e('Option ID', 'nhrrob-options-table-manager'); ?></th> 57 67 <th><?php esc_html_e('Option Name', 'nhrrob-options-table-manager'); ?></th> -
nhrrob-options-table-manager/trunk/nhrrob-options-table-manager.php
r3405973 r3434009 6 6 * Author: Nazmul Hasan Robin 7 7 * Author URI: https://profiles.wordpress.org/nhrrob/ 8 * Version: 1.1. 88 * Version: 1.1.9 9 9 * Requires at least: 6.0 10 10 * Requires PHP: 7.4 … … 28 28 * @var string 29 29 */ 30 const nhrotm_version = '1.1. 8';30 const nhrotm_version = '1.1.9'; 31 31 32 32 /** -
nhrrob-options-table-manager/trunk/readme.txt
r3405973 r3434009 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1.1. 87 Stable tag: 1.1.9 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 38 38 We're constantly improving NHR Options Table Manager! Here's what's on the way: 39 39 - **Bulk Deletion** – Quickly remove multiple options and user meta entries at once. 40 - **WP Recipe Maker Table Support** – Manage recipe-related data efficiently.41 - **Expired Transient Deletion** – Automatically clean up expired transients to free up database space.42 40 - **More Exciting Features** – Stay tuned for additional enhancements! 43 41 … … 85 83 86 84 == Changelog == 85 86 = 1.1.9 - 05/01/2026 = 87 - Added: Bulk delete options feature 87 88 88 89 = 1.1.8 - 30/11/2025 =
Note: See TracChangeset
for help on using the changeset viewer.