Changeset 3380967
- Timestamp:
- 10/19/2025 08:22:54 PM (5 months ago)
- Location:
- 0-day-analytics
- Files:
-
- 6 added
- 46 edited
- 1 copied
-
tags/3.8.0 (copied) (copied from 0-day-analytics/trunk)
-
tags/3.8.0/advanced-analytics.php (modified) (4 diffs)
-
tags/3.8.0/classes/vendor/controllers/class-endpoints.php (modified) (2 diffs)
-
tags/3.8.0/classes/vendor/entities/class-abstract-entity.php (modified) (1 diff)
-
tags/3.8.0/classes/vendor/helpers/class-ajax-helper.php (modified) (3 diffs)
-
tags/3.8.0/classes/vendor/helpers/class-miscellaneous.php (added)
-
tags/3.8.0/classes/vendor/helpers/class-settings.php (modified) (1 diff)
-
tags/3.8.0/classes/vendor/helpers/class-transients-helper.php (modified) (11 diffs)
-
tags/3.8.0/classes/vendor/lists/class-crons-list.php (modified) (4 diffs)
-
tags/3.8.0/classes/vendor/lists/class-logs-list.php (modified) (3 diffs)
-
tags/3.8.0/classes/vendor/lists/class-requests-list.php (modified) (8 diffs)
-
tags/3.8.0/classes/vendor/lists/class-table-list.php (modified) (8 diffs)
-
tags/3.8.0/classes/vendor/lists/class-transients-list.php (modified) (9 diffs)
-
tags/3.8.0/classes/vendor/lists/class-wp-mail-list.php (modified) (6 diffs)
-
tags/3.8.0/classes/vendor/lists/entity/class-common-table.php (modified) (3 diffs)
-
tags/3.8.0/classes/vendor/lists/traits/class-list-trait.php (modified) (1 diff)
-
tags/3.8.0/classes/vendor/lists/views/class-requests-view.php (modified) (1 diff)
-
tags/3.8.0/classes/vendor/lists/views/class-table-view.php (modified) (5 diffs)
-
tags/3.8.0/classes/vendor/lists/views/class-transients-view.php (modified) (5 diffs)
-
tags/3.8.0/classes/vendor/lists/views/class-wp-mail-view.php (modified) (1 diff)
-
tags/3.8.0/css/admin-export-csv.css (added)
-
tags/3.8.0/css/admin/style.css (modified) (1 diff)
-
tags/3.8.0/js/admin-export-csv.js (added)
-
tags/3.8.0/js/admin/aadvana-settings.js (modified) (4 diffs)
-
tags/3.8.0/readme.txt (modified) (3 diffs)
-
tags/3.8.0/vendor/composer/autoload_classmap.php (modified) (1 diff)
-
tags/3.8.0/vendor/composer/autoload_static.php (modified) (1 diff)
-
trunk/advanced-analytics.php (modified) (4 diffs)
-
trunk/classes/vendor/controllers/class-endpoints.php (modified) (2 diffs)
-
trunk/classes/vendor/entities/class-abstract-entity.php (modified) (1 diff)
-
trunk/classes/vendor/helpers/class-ajax-helper.php (modified) (3 diffs)
-
trunk/classes/vendor/helpers/class-miscellaneous.php (added)
-
trunk/classes/vendor/helpers/class-settings.php (modified) (1 diff)
-
trunk/classes/vendor/helpers/class-transients-helper.php (modified) (11 diffs)
-
trunk/classes/vendor/lists/class-crons-list.php (modified) (4 diffs)
-
trunk/classes/vendor/lists/class-logs-list.php (modified) (3 diffs)
-
trunk/classes/vendor/lists/class-requests-list.php (modified) (8 diffs)
-
trunk/classes/vendor/lists/class-table-list.php (modified) (8 diffs)
-
trunk/classes/vendor/lists/class-transients-list.php (modified) (9 diffs)
-
trunk/classes/vendor/lists/class-wp-mail-list.php (modified) (6 diffs)
-
trunk/classes/vendor/lists/entity/class-common-table.php (modified) (3 diffs)
-
trunk/classes/vendor/lists/traits/class-list-trait.php (modified) (1 diff)
-
trunk/classes/vendor/lists/views/class-requests-view.php (modified) (1 diff)
-
trunk/classes/vendor/lists/views/class-table-view.php (modified) (5 diffs)
-
trunk/classes/vendor/lists/views/class-transients-view.php (modified) (5 diffs)
-
trunk/classes/vendor/lists/views/class-wp-mail-view.php (modified) (1 diff)
-
trunk/css/admin-export-csv.css (added)
-
trunk/css/admin/style.css (modified) (1 diff)
-
trunk/js/admin-export-csv.js (added)
-
trunk/js/admin/aadvana-settings.js (modified) (4 diffs)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/vendor/composer/autoload_classmap.php (modified) (1 diff)
-
trunk/vendor/composer/autoload_static.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
0-day-analytics/tags/3.8.0/advanced-analytics.php
r3378902 r3380967 11 11 * Plugin Name: 0 Day Analytics 12 12 * Description: Take full control of error log, crons, transients, plugins, requests, mails and DB tables. 13 * Version: 3. 7.613 * Version: 3.8.0 14 14 * Author: Stoil Dobrev 15 15 * Author URI: https://github.com/sdobreff/ … … 37 37 // Constants. 38 38 if ( ! defined( 'ADVAN_VERSION' ) ) { 39 define( 'ADVAN_VERSION', '3. 7.6' );39 define( 'ADVAN_VERSION', '3.8.0' ); 40 40 define( 'ADVAN_TEXTDOMAIN', '0-day-analytics' ); 41 41 define( 'ADVAN_NAME', '0 Day Analytics' ); … … 129 129 \add_action( 'wp_mail_failed', array( WP_Error_Handler::class, 'on_mail_error' ), -1 ); 130 130 131 \add_action( 'plugin_loaded', 'advana_remove_plugins' );132 \add_action( 'network_plugin_loaded', 'advana_remove_plugins' );131 // \add_action( 'plugin_loaded', 'advana_remove_plugins' ); 132 // \add_action( 'network_plugin_loaded', 'advana_remove_plugins' ); 133 133 134 134 if ( ! WP_Helper::is_multisite() && \wp_is_recovery_mode() ) { … … 220 220 * Because of its extremely poor implementation, the log-iq plugin must be deactivated as it interferes very badly with the proper WP work. 221 221 */ 222 if ( false !== strpos( $plugin, 'log-iq' . DIRECTORY_SEPARATOR ) ) {223 \deactivate_plugins( $plugin, true, null );224 }222 // if ( false !== strpos( $plugin, 'log-iq' . DIRECTORY_SEPARATOR ) ) { 223 // \deactivate_plugins( $plugin, true, null ); 224 // } 225 225 } 226 226 } -
0-day-analytics/tags/3.8.0/classes/vendor/controllers/class-endpoints.php
r3377720 r3380967 16 16 17 17 use ADVAN\Lists\Logs_List; 18 use ADVAN\Lists\WP_Mail_List; 18 19 use ADVAN\Lists\Requests_List; 20 use ADVAN\Helpers\Crons_Helper; 21 use ADVAN\Helpers\Transients_Helper; 19 22 use ADVAN\Entities_Global\Common_Table; 20 use ADVAN\Helpers\Crons_Helper;21 use ADVAN\Lists\WP_Mail_List;22 23 23 24 defined( 'ABSPATH' ) || exit; // Exit if accessed directly. … … 242 243 'pattern' => '.+', 243 244 'description' => 'ID of the table record which row needs to be shown', 245 ), 246 ), 247 'checkPermissions' => array( __CLASS__, 'check_permissions' ), 248 'showInIndex' => false, 249 ), 250 ), 251 ), 252 ), 253 'get_transient_record' => array( 254 'class' => Transients_Helper::class, 255 'namespace' => self::ENDPOINT_ROOT_NAME . '/v1', 256 257 'endpoints' => array( 258 array( 259 '(?P<transient_id>\w+)' => array( 260 'methods' => array( 261 'method' => \WP_REST_Server::READABLE, 262 'callback' => 'get_transient_by_id', 263 ), 264 'args' => array( 265 'transient_id' => array( 266 'required' => true, 267 'type' => 'string', 268 'pattern' => '\d+', 269 'description' => 'Transient hash', 244 270 ), 245 271 ), -
0-day-analytics/tags/3.8.0/classes/vendor/entities/class-abstract-entity.php
r3375967 r3380967 770 770 return $results; 771 771 } 772 773 /** 774 * Returns all column names which belong to the table 775 * 776 * @return array 777 * 778 * @since latest 779 */ 780 public static function get_all_columns(): array { 781 return ( static::class )::$fields; 782 } 772 783 } 773 784 } -
0-day-analytics/tags/3.8.0/classes/vendor/helpers/class-ajax-helper.php
r3377720 r3380967 12 12 namespace ADVAN\Helpers; 13 13 14 use ADVAN\Lists\Logs_List; 14 15 use ADVAN\Helpers\Settings; 16 use ADVAN\Lists\Crons_List; 17 use ADVAN\Lists\Table_List; 15 18 use ADVAN\Controllers\Slack; 16 19 use ADVAN\Helpers\WP_Helper; 20 use ADVAN\Lists\WP_Mail_List; 21 use ADVAN\Lists\Requests_List; 17 22 use ADVAN\Controllers\Telegram; 18 23 use ADVAN\Controllers\Error_Log; 24 use ADVAN\Controllers\Slack_API; 25 use ADVAN\Lists\Transients_List; 26 use ADVAN\Controllers\Telegram_API; 27 use ADVAN\Entities_Global\Common_Table; 19 28 use ADVAN\Controllers\Mail_SMTP_Settings; 20 use ADVAN\Controllers\Slack_API;21 use ADVAN\Controllers\Telegram_API;22 use ADVAN\Lists\Logs_List;23 29 24 30 // Exit if accessed directly. … … 141 147 142 148 \add_action( 'wp_ajax_advana_error_log_filtering_dismiss_notice', array( __CLASS__, 'error_log_filtering_dismiss_notice' ) ); 149 150 \add_action( 'wp_ajax_aadvana_export_large_csv', array( __CLASS__, 'export_large_csv' ) ); 151 \add_action( 'wp_ajax_aadvana_export_large_csv_cleanup', array( __CLASS__, 'export_large_csv_cleanup' ) ); 143 152 } 144 153 } … … 650 659 \wp_die(); 651 660 } 661 662 /** 663 * Export Large CSV in Batches 664 * 665 * @return void 666 * 667 * @since latest 668 */ 669 public static function export_large_csv() { 670 WP_Helper::verify_admin_nonce( 'export_large_csv_nonce', 'security' ); 671 672 $batch = isset( $_POST['batch'] ) ? intval( $_POST['batch'] ) : 0; 673 $batch_size = isset( $_POST['batch_size'] ) ? intval( $_POST['batch_size'] ) : 500; 674 $offset = $batch * $batch_size; 675 676 list($export_dir, $export_url) = Miscellaneous::get_export_dir(); 677 678 $csv_path = $export_dir . 'export_temp.csv'; 679 $csv_url = $export_url . 'export_temp.csv'; 680 681 $rows = array(); 682 $total = 0; 683 $extra_file_name = ''; 684 685 if ( isset( $_POST['typeExport'] ) && ! empty( $_POST['typeExport'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 686 if ( 'cron' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 687 $rows = Crons_List::get_cron_items(); 688 $rows = \array_slice( $rows, $offset, $batch_size, true ); 689 $total = count( $rows ); 690 } 691 if ( 'logs' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 692 693 $plugin_filter = ( ( isset( $_POST['plugin_filter'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['plugin_filter'] ) ) : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing 694 695 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 696 697 $extra_file_name = '_' . $plugin_filter . '_'; 698 699 $list_logs = new Logs_List( array( 'plugin_filter' => $plugin_filter ) ); 700 701 $rows = $list_logs::get_error_items(); 702 $rows = \array_slice( $rows, $offset, $batch_size, true ); 703 704 foreach ( $rows as $key => $row ) { 705 if ( isset( $row['sub_items'] ) ) { 706 if ( \is_array( $row['sub_items'] ) && ! empty( $row['sub_items'] ) ) { 707 $subs = array(); 708 foreach ( $row['sub_items'] as $sub_key => $sub_item ) { 709 $subs[] = \json_encode( $sub_item ); 710 } 711 712 $rows[ $key ]['sub_items'] = $subs; 713 } 714 } else { 715 $rows[ $key ]['sub_items'] = ''; 716 } 717 if ( !isset( $row['plugin'] ) ) { 718 $rows[ $key ]['plugin'] = ''; 719 } 720 } 721 722 $total = count( $rows ); 723 } 724 if ( 'table' === $_POST['typeExport'] && isset( $_POST['tableName'] ) && ! empty( $_POST['tableName'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 725 $table = \sanitize_text_field( \wp_unslash( $_POST['tableName'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing 726 727 $search = isset( $_POST['search'] ) ? \sanitize_text_field( \wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 728 729 $extra_file_name = '_' . str_replace( ' ', '_', $table ) . '_'; 730 if ( Common_Table::check_table_exists( $table ) ) { 731 $list_table = new Table_List( $table ); 732 733 $rows = $list_table->fetch_table_data( 734 array( 735 'per_page' => $batch_size, 736 'offset' => $offset, 737 'order' => 'ASC', 738 'search_string' => $search, 739 ) 740 ); 741 742 $total = $list_table->get_count(); 743 } 744 } 745 if ( 'mail' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 746 747 $list_table = new WP_Mail_List(); 748 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 749 $extra_file_name = '_' . str_replace( ' ', '_', $list_table->get_table_name() ) . '_'; 750 751 $rows = $list_table->fetch_table_data( 752 array( 753 'per_page' => $batch_size, 754 'offset' => $offset, 755 'order' => 'ASC', 756 'site_id' => '', 757 'search' => $search, 758 ) 759 ); 760 761 $total = $list_table->get_count(); 762 } 763 if ( 'requests' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 764 765 $list_table = new Requests_List(); 766 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 767 $plugin = isset( $_POST['plugin'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 768 $extra_file_name = '_' . str_replace( ' ', '_', $list_table->get_table_name() ) . '_'; 769 770 $rows = $list_table->fetch_table_data( 771 array( 772 'per_page' => $batch_size, 773 'offset' => $offset, 774 'order' => 'ASC', 775 'search_string' => $search, 776 'plugin' => $plugin, 777 ) 778 ); 779 780 $total = $list_table->get_count(); 781 } 782 if ( 'transients' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 783 784 $list_table = new Transients_List( array() ); 785 786 $type = isset( $_POST['transientType'] ) ? sanitize_text_field( wp_unslash( $_POST['transientType'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 787 788 $extra_file_name = '_' . str_replace( ' ', '_', $list_table->get_table_name() ) . '_' . $type . '_'; 789 790 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 791 792 $rows = $list_table->fetch_table_data( 793 array( 794 'per_page' => $batch_size, 795 'offset' => $offset, 796 'order' => 'ASC', 797 'type' => $type, 798 'search' => $search, 799 ) 800 ); 801 802 $total = $list_table->get_count(); 803 } 804 } else { 805 \wp_send_json_error( 806 array( 807 'message' => __( 'Export type is not specified.', '0-day-analytics' ), 808 ), 809 400 810 ); 811 } 812 813 if ( empty( $rows ) ) { 814 // Open CSV for writing/appending. 815 $handle = @fopen( $csv_path, $is_first_batch ? 'w' : 'a' ); 816 if ( ! $handle ) { 817 \wp_send_json_error( 818 array( 819 'message' => __( 'Failed to write to CSV file. Check folder permissions.', '0-day-analytics' ), 820 ), 821 500 822 ); 823 } 824 825 // Get date and time formats from WordPress settings. 826 $date_format = get_option( 'date_format' ); // e.g., 'F j, Y'. 827 $time_format = get_option( 'time_format' ); // e.g., 'g:i a'. 828 829 // Combine date and time if needed. 830 $formatted_datetime = date_i18n( $date_format . ' ' . $time_format ); 831 832 // Sanitize filename: replace spaces and colons with dashes. 833 $safe_datetime = preg_replace( '/[^A-Za-z0-9\-]/', '-', $formatted_datetime ); 834 835 // Create filename. 836 $filename = 'export_' . $_POST['typeExport'] . '_' . $extra_file_name . $safe_datetime . '.csv'; 837 838 rename( $export_dir . 'export_temp.csv', $export_dir . $filename ); // phpcs:ignore WordPress.WP.AlternativeFunctions.rename_rename 839 840 \wp_send_json_success( 841 array( 842 'done' => true, 843 'download_url' => $export_url . $filename, 844 ) 845 ); 846 } 847 848 $is_first_batch = ( 0 === $batch ); 849 850 // Open CSV for writing/appending. 851 $handle = @fopen( $csv_path, $is_first_batch ? 'w' : 'a' ); 852 if ( ! $handle ) { 853 \wp_send_json_error( 854 array( 855 'message' => __( 'Failed to write to CSV file. Check folder permissions.', '0-day-analytics' ), 856 ), 857 500 858 ); 859 } 860 861 if ( $is_first_batch && ! empty( $rows ) ) { 862 fputcsv( 863 $handle, 864 array_keys( reset( $rows ) ), 865 ',', 866 '"', 867 '\\', 868 ); 869 } 870 871 foreach ( $rows as $row ) { 872 \fputcsv( 873 $handle, 874 array_map( 875 function ( $value ): string { 876 // Convert to string. 877 if ( is_array( $value ) ) { 878 $value = \implode( ', ', $value ); 879 } 880 if ( is_object( $value ) ) { 881 $value = json_encode( $value ); 882 } 883 $value = (string) $value; 884 885 // Convert escaped sequences like \" \n \t into real .characters. 886 $value = stripcslashes( $value ); 887 888 // Remove control characters (non-printable). 889 $value = preg_replace( '/[\x00-\x1F\x7F]/u', '', $value ); 890 891 return (string) $value; 892 }, 893 $row 894 ), 895 ',', 896 '"', 897 '\\', 898 ); 899 } 900 901 fclose( $handle ); 902 903 \wp_send_json_success( 904 array( 905 'done' => false, 906 'next_batch' => $batch + 1, 907 'processed' => ( $batch + 1 ) * $batch_size, 908 'total' => $total, 909 ) 910 ); 911 } 912 913 /** 914 * Cleanup Temporary CSV 915 * 916 * @return void 917 * 918 * @since latest 919 */ 920 public static function export_large_csv_cleanup() { 921 WP_Helper::verify_admin_nonce( 'export_large_csv_nonce', 'security' ); 922 923 list($export_dir) = Miscellaneous::get_export_dir(); 924 925 $csv_path = $export_dir . 'export_temp.csv'; 926 927 if ( file_exists( $csv_path ) ) { 928 unlink( $csv_path ); 929 \wp_send_json_success( array( 'deleted' => true ) ); 930 } else { 931 \wp_send_json_success( array( 'deleted' => false ) ); 932 } 933 } 652 934 } 653 935 } -
0-day-analytics/tags/3.8.0/classes/vendor/helpers/class-settings.php
r3374674 r3380967 306 306 'wp-api-fetch' 307 307 ); 308 309 // Exporting CSV start. 310 311 \wp_enqueue_style( 312 'oda-admin-export-style', 313 ADVAN_PLUGIN_ROOT_URL . 'css/admin-export-csv.css', 314 array(), 315 '1.1' 316 ); 317 318 \wp_enqueue_script( 319 'aadvana-admin-export-js', 320 ADVAN_PLUGIN_ROOT_URL . 'js/admin-export-csv.js', 321 array(), 322 '1.1', 323 true 324 ); 325 326 \wp_localize_script( 327 'aadvana-admin-export-js', 328 'aadvanaExport', 329 array( 330 'ajax_url' => admin_url( 'admin-ajax.php' ), 331 'nonce' => wp_create_nonce( 'export_large_csv_nonce' ), 332 'i18n' => array( 333 'starting' => __( 'Starting export...', '0-day-analytics' ), 334 'exporting' => __( 'Exporting...', '0-day-analytics' ), 335 'completed' => __( '✅ Export complete! Downloading...', '0-day-analytics' ), 336 'cancelled' => __( '❌ Export cancelled.', '0-day-analytics' ), 337 'networkError' => __( 'Network error', '0-day-analytics' ), 338 'error' => __( 'Error during export:', '0-day-analytics' ), 339 'unauthorized' => __( 'Unauthorized', '0-day-analytics' ), 340 'csvExportBtnTitle' => __( 'CSV Export', '0-day-analytics' ), 341 ), 342 ) 343 ); 344 // Exporting CSV end. 308 345 309 346 ?> -
0-day-analytics/tags/3.8.0/classes/vendor/helpers/class-transients-helper.php
r3374674 r3380967 15 15 16 16 use ADVAN\Lists\Transients_List; 17 use ADVAN\Entities_Global\Common_Table; 17 18 18 19 // Exit if accessed directly. … … 148 149 * Retrieve a transient by its ID 149 150 * 150 * @param int $id - The ID of the transient to retrieve. 151 * @param \WP_REST_Request $request - The request object. 152 * @param int $id - The ID of the transient to retrieve. 151 153 * 152 154 * @return array 153 155 * 154 156 * @since 1.8.5 155 */ 156 public static function get_transient_by_id( $id = 0 ) { 157 * @since latest - Added $request parameter. 158 */ 159 public static function get_transient_by_id( ?\WP_REST_Request $request = null, $id = 0 ) { 157 160 global $wpdb; 158 161 … … 161 164 // Bail if empty ID. 162 165 if ( empty( $id ) ) { 163 return false; 166 if ( null !== $request ) { 167 $id = $request->get_param( 'transient_id' ); 168 } 169 if ( empty( $id ) ) { 170 return false; 171 } 164 172 } 165 173 … … 168 176 169 177 // Query. 170 return $wpdb->get_row( $prepared, ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared 178 $transient = $wpdb->get_row( $prepared, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 179 if ( null === $request ) { 180 return $transient; 181 } elseif ( ! empty( $transient ) ) { 182 \ob_start(); 183 184 $name = self::get_transient_name( $transient['option_name'] ); 185 186 if ( in_array( $name, self::WP_CORE_TRANSIENTS ) ) { 187 ?> 188 <div id="advaa-status-notice" class="notice notice-warning"> 189 <p><?php esc_html_e( 'This is a WP core transient', '0-day-analytics' ); ?></p> 190 </div> 191 <?php 192 } else { 193 foreach ( self::WP_CORE_TRANSIENTS as $trans_name ) { 194 if ( \str_starts_with( $name, $trans_name ) ) { 195 ?> 196 <div id="advaa-status-notice" class="notice notice-warning"> 197 <p><?php esc_html_e( 'This is a WP core transient, even if you update it, the new value will be overridden by the core!', '0-day-analytics' ); ?></p> 198 </div> 199 <?php 200 break; 201 } 202 } 203 } 204 ?> 205 <table class="widefat striped table-view-list" style="max-width:100%;table-layout: fixed;"> 206 <col width="20%" /> 207 <col width="80%" /> 208 <thead> 209 <tr> 210 <th> 211 <?php echo \esc_html_e( 'Name', '0-day-analytics' ); ?> 212 </th> 213 <th> 214 <?php echo \esc_html_e( 'Value', '0-day-analytics' ); ?> 215 </th> 216 </tr> 217 </thead> 218 <tbody> 219 <tr> 220 <th><?php esc_html_e( 'Option ID', '0-day-analytics' ); ?></th> 221 <td><?php echo esc_attr( $transient['option_id'] ); ?></td> 222 </tr> 223 <tr> 224 <th><?php \esc_html_e( 'Name', '0-day-analytics' ); ?></th> 225 <td><?php echo \esc_attr( self::clear_transient_name( $transient['option_name'] ) ); ?> 226 </tr> 227 <?php 228 $expiration = self::get_transient_expiration_time( $transient['option_name'] ); 229 if ( 0 !== $expiration ) { 230 231 $next_run_gmt = gmdate( 'Y-m-d H:i:s', $expiration ); 232 $next_run_date_local = \get_date_from_gmt( $next_run_gmt, 'Y-m-d' ); 233 $next_run_time_local = \get_date_from_gmt( $next_run_gmt, 'H:i:s' ); 234 } 235 if ( 0 !== $expiration ) { 236 ?> 237 <tr> 238 <th><?php \esc_html_e( 'Expiration', '0-day-analytics' ); ?></th> 239 <td> 240 <?php 241 echo \esc_attr( $next_run_date_local ) . ' ' . \esc_attr( $next_run_time_local ); 242 ?> 243 </td> 244 </tr> 245 <?php 246 } else { 247 248 } 249 250 ?> 251 <tr> 252 <th><?php esc_html_e( 'Value', '0-day-analytics' ); ?></th> 253 <td> 254 <?php echo Common_Table::format_value_for_html( $transient['option_value'] ); ?> 255 </td> 256 </tr> 257 </tbody> 258 </table> 259 <?php 260 $message = \ob_get_clean(); 261 262 return rest_ensure_response( 263 array( 264 'success' => true, 265 'mail_body' => $message, 266 'transient_name' => $name, 267 ) 268 ); 269 270 } else { 271 return new \WP_Error( 272 'empty_row', 273 __( 'No record found.', '0-day-analytics' ), 274 array( 'status' => 400 ) 275 ); 276 } 171 277 } 172 278 … … 334 440 $type = \esc_html__( 'json', '0-day-analytics' ); 335 441 } elseif ( is_string( $value ) && in_array( $value, array( 'no', 'yes', 'false', 'true' ), true ) ) { 336 $type = \esc_html__( 'boolean?', '0-day-analytics' );442 $type = \esc_html__( 'boolean?', '0-day-analytics' ); 337 443 338 444 // Scalar. … … 392 498 393 499 // Escape some LIKE parts. 394 $esc_name = '' . $wpdb->esc_like( '_transient_' ) . '%';500 $esc_name = '' . $wpdb->esc_like( '_transient_' ) . '%'; 395 501 $esc_site_name = '' . $wpdb->esc_like( '_site_transient_' ) . '%'; 396 $esc_time = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%';502 $esc_time = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%'; 397 503 398 504 // SELECT. … … 410 516 // if ( empty( $parsed_args['count'] ) ) { 411 517 412 // FROM.413 518 // FROM. 519 414 520 // old - ON d.option_name LIKE CONCAT('%_transient_timeout_', SUBSTRING_INDEX( go.option_name, '_transient_', -1 ), '%') 415 521 416 $sql[] = "LEFT JOIN522 $sql[] = "LEFT JOIN 417 523 {$wpdb->options} d 418 524 ON d.option_name = CONCAT( … … 456 562 if ( empty( $parsed_args['count'] ) && empty( $parsed_args['all'] ) ) { 457 563 $offset = absint( $parsed_args['offset'] ); 458 $ number = absint( $parsed_args['number'] );564 $per_page = absint( $parsed_args['per_page'] ); 459 565 460 566 // if ( ! empty( $parsed_args['orderby'] ) && \in_array( $parsed_args['orderby'], array( 'transient_name' ) ) ) { … … 475 581 // ); 476 582 // } else { 477 $sql[] = $wpdb->prepare( 'ORDER BY option_id DESC LIMIT %d, %d', $offset, $number);583 $sql[] = $wpdb->prepare( 'ORDER BY option_id DESC LIMIT %d, %d', $offset, $per_page ); 478 584 // } 479 585 } … … 487 593 // Query. 488 594 $transients = empty( $parsed_args['count'] ) 489 ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared490 : $wpdb->get_var( $prepared, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared595 ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 596 : $wpdb->get_var( $prepared, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 491 597 492 598 if ( empty( $parsed_args['count'] ) && ! empty( $transients ) ) { … … 496 602 'transient_name' => self::get_transient_name( $transient['option_name'] ), 497 603 'value' => self::get_transient_value( $transient['option_value'] ), 498 'schedule' => (int) $transient['schedule'] ,604 'schedule' => (int) $transient['schedule'], 499 605 'id' => $transient['option_id'], 500 606 ); -
0-day-analytics/tags/3.8.0/classes/vendor/lists/class-crons-list.php
r3378902 r3380967 352 352 * 353 353 * @since 1.1.0 354 * @since 2.9.0 - Introduced flag getting the events wi htout the type filtering354 * @since 2.9.0 - Introduced flag getting the events without the type filtering 355 355 */ 356 356 public static function get_cron_items( bool $no_type_filtering = false ): array { … … 926 926 </select> 927 927 <?php \submit_button( __( 'Filter', '0-day-analytics' ), '', 'filter_action', false, array( 'id' => 'schedules-submit' ) ); ?> 928 </div> 929 <div id="export-form"> 930 <div> 931 <button id="start-export" class="button" data-type-export="cron"> 932 <?php echo esc_html__( 'CSV Export', '0-day-analytics' ); ?> 933 </button> 934 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 935 <?php echo esc_html__( 'Cancel', '0-day-analytics' ); ?> 936 </button> 937 </div> 938 939 <div id="progress-container" class="progress-wrap" style="display:none;"> 940 <div id="progress-bar"></div> 941 </div> 942 943 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 928 944 </div> 929 945 <?php … … 1136 1152 return sprintf( 1137 1153 $format, 1138 esc_attr( $link ),1139 esc_html( $text ),1154 \esc_attr( $link ), 1155 \esc_html( $text ), 1140 1156 ( 'edit' ) 1141 1157 ); … … 1202 1218 * @since 1.4.0 1203 1219 */ 1204 p rotectedfunction get_table_classes() {1220 public function get_table_classes() { 1205 1221 return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] ); 1206 1222 } -
0-day-analytics/tags/3.8.0/classes/vendor/lists/class-logs-list.php
r3377720 r3380967 1123 1123 <?php 1124 1124 } 1125 } 1126 if ( 'top' === $which && count(self::$items_collected) > 0 ) { 1127 ?> 1128 <div id="export-form" style="display:inline-block;"> 1129 <div> 1130 <button id="start-export" class="button" data-type-export="logs" data-search="<?php echo \esc_attr( self::escaped_search_input() ); ?>" data-plugin-filter="<?php echo ( isset( self::$query_args['plugin_filter'] ) ) ? \esc_attr( self::$query_args['plugin_filter'] ) : '-1'; ?>"> 1131 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 1132 </button> 1133 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 1134 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 1135 </button> 1136 </div> 1137 1138 <div id="progress-container" class="progress-wrap" style="display:none;"> 1139 <div id="progress-bar"></div> 1140 </div> 1141 1142 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 1143 </div> 1144 1145 <?php 1125 1146 } 1126 1147 ?> … … 1345 1366 </select> 1346 1367 </div> 1347 <?php 1348 $dismissed = \get_user_meta( \get_current_user_id(), '_aadvana_filter_error_log_notice_dismissed', true ); 1349 1350 if ( ! $dismissed ) { 1351 ?> 1368 <?php 1369 1370 $dismissed = \get_user_meta( \get_current_user_id(), '_aadvana_filter_error_log_notice_dismissed', true ); 1371 1372 if ( ! $dismissed ) { 1373 ?> 1352 1374 1353 1375 <div id="advaa-filtering-notice" class="notice notice-info is-dismissible"> … … 1367 1389 }); 1368 1390 </script> 1369 <?php1370 }1371 ?>1391 <?php 1392 } 1393 ?> 1372 1394 <script> 1373 1395 -
0-day-analytics/tags/3.8.0/classes/vendor/lists/class-requests-list.php
r3375967 r3380967 18 18 use ADVAN\Helpers\WP_Helper; 19 19 use ADVAN\Helpers\File_Helper; 20 use ADVAN\ Entities_Global\Common_Table;20 use ADVAN\Helpers\Miscellaneous; 21 21 use ADVAN\Lists\Traits\List_Trait; 22 22 use ADVAN\ControllersApi\Endpoints; … … 24 24 use ADVAN\Helpers\Plugin_Theme_Helper; 25 25 use ADVAN\Entities\Requests_Log_Entity; 26 use ADVAN\Entities_Global\Common_Table; 26 27 27 28 if ( ! class_exists( 'WP_List_Table' ) ) { … … 207 208 $this->handle_table_actions(); 208 209 209 $items = $this->fetch_table_data(); 210 global $wpdb; 211 212 $per_page = self::get_screen_option_per_page(); 213 214 $current_page = $this->get_pagenum(); 215 if ( 1 < $current_page ) { 216 $offset = $per_page * ( $current_page - 1 ); 217 } else { 218 $offset = 0; 219 } 220 221 $search_string = self::escaped_search_input(); 222 223 if ( isset( $_REQUEST['plugin'] ) && ! empty( $_REQUEST['plugin'] ) ) { 224 if ( -1 === (int) $_REQUEST['plugin'] ) { 225 $plugin = -1; 226 } else { 227 $plugin = \sanitize_text_field( \wp_unslash( $_REQUEST['plugin'] ) ); 228 } 229 } else { 230 $plugin = ''; 231 } 232 233 $wpdb_table = $this->get_table_name(); 234 235 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : 'id'; 236 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'DESC'; 237 238 $items = $this->fetch_table_data( 239 array( 240 'search_string' => $search_string, 241 'offset' => $offset, 242 'per_page' => $per_page, 243 'wpdb_table' => $wpdb_table, 244 'orderby' => $orderby, 245 'order' => $order, 246 'plugin' => $plugin, 247 ) 248 ); 210 249 211 250 $columns = self::manage_columns( array() ); … … 282 321 * Fetch table data from the WordPress database. 283 322 * 323 * @param array $args - The arguments collected / passed. 324 * 284 325 * @since 1.0.0 326 * @since latest - added $args param. 285 327 * 286 328 * @return Array 287 329 */ 288 public function fetch_table_data( ) {330 public function fetch_table_data( array $args = array() ) { 289 331 290 332 global $wpdb; 291 333 292 $per_page = self::get_screen_option_per_page(); 293 294 $current_page = $this->get_pagenum(); 295 if ( 1 < $current_page ) { 296 $offset = $per_page * ( $current_page - 1 ); 297 } else { 298 $offset = 0; 299 } 300 301 $search_string = self::escaped_search_input(); 302 303 if ( isset( $_REQUEST['plugin'] ) && ! empty( $_REQUEST['plugin'] ) ) { 304 if ( -1 === (int) $_REQUEST['plugin'] ) { 305 $plugin = -1; 306 } else { 307 $plugin = \sanitize_text_field( \wp_unslash( $_REQUEST['plugin'] ) ); 308 } 309 } else { 310 $plugin = ''; 311 } 334 // Parse. 335 $parsed_args = \wp_parse_args( 336 $args, 337 array( 338 'offset' => 0, 339 'search_string' => self::escaped_search_input(), 340 'per_page' => self::get_screen_option_per_page(), 341 'wpdb_table' => $this->get_table_name(), 342 'search_sql' => '', 343 'orderby' => self::$table::get_real_id_name(), 344 'order' => 'DESC', 345 'count' => false, 346 'plugin' => '', 347 ) 348 ); 349 350 $search_string = $parsed_args['search_string']; 351 $offset = $parsed_args['offset']; 352 $per_page = $parsed_args['per_page']; 353 $wpdb_table = $parsed_args['wpdb_table']; 354 $orderby = $parsed_args['orderby']; 355 $order = $parsed_args['order']; 356 $plugin = $parsed_args['plugin']; 312 357 313 358 $search_sql = ''; … … 315 360 if ( '' !== $search_string ) { 316 361 $search_sql = 'AND (id LIKE "%' . $wpdb->esc_like( $search_string ) . '%"'; 317 foreach ( array_keys( Requests_Log_Entity::get_ column_names_admin() ) as $value ) {362 foreach ( array_keys( Requests_Log_Entity::get_all_columns() ) as $value ) { 318 363 $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" '; 319 364 } … … 321 366 } 322 367 323 if ( '' !== $plugin && -1 !== (int) $plugin ) {368 if ( '' !== $plugin && -1 !== (int) $plugin && 0 !== (int) $plugin ) { 324 369 $search_sql .= ' AND plugin = "' . (string) $plugin . '" '; 325 370 } … … 327 372 $wpdb_table = $this->get_table_name(); 328 373 329 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : 'id'; 330 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'DESC'; 331 $query = 'SELECT 374 $query = 'SELECT 332 375 ' . implode( ', ', \array_keys( Requests_Log_Entity::get_fields() ) ) . ' 333 376 FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order; … … 757 800 </script> 758 801 <?php 759 802 if ( 'top' === $which && $this->count > 0 ) { 803 ?> 804 <div id="export-form"> 805 <div> 806 <button id="start-export" class="button" data-type-export="requests" data-search="<?php echo \esc_attr( self::escaped_search_input() ); ?>" data-plugin="<?php echo \esc_attr( $plugin ); ?>"> 807 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 808 </button> 809 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 810 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 811 </button> 812 </div> 813 814 <div id="progress-container" class="progress-wrap" style="display:none;"> 815 <div id="progress-bar"></div> 816 </div> 817 818 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 819 </div> 820 821 <?php 822 } 760 823 if ( 'top' === $which ) { 761 824 ?> 762 825 <style> 763 .flex { 764 display:flex; 765 } 766 .flex-row { 767 flex-direction:row; 768 } 769 .grow-0 { 770 flex-grow:0; 771 } 772 .p-2 { 773 padding:8px; 774 } 775 .w-full { 776 width:auto; 777 } 778 .border-t { 779 border-bottom-width:1px; 780 } 781 .justify-between { 782 justify-content:space-between; 783 } 784 .italic { 785 font-style: italic; 786 } 787 .text-lg { 788 font-size: 1.1em; 789 font-weight: bold; 790 } 791 #wpwrap { 792 overflow-x: hidden !important; 793 } 794 .wp-list-table { 795 white-space: nowrap; 796 display: block; 797 overflow-x: auto; 798 } 826 <?php echo Miscellaneous::get_flex_style(); ?> 799 827 /* .wp-list-table { 800 828 display: block; -
0-day-analytics/tags/3.8.0/classes/vendor/lists/class-table-list.php
r3377720 r3380967 18 18 use ADVAN\Helpers\WP_Helper; 19 19 use ADVAN\Helpers\File_Helper; 20 use ADVAN\ Entities_Global\Common_Table;20 use ADVAN\Helpers\Miscellaneous; 21 21 use ADVAN\Lists\Views\Table_View; 22 22 use ADVAN\Lists\Traits\List_Trait; 23 use ADVAN\Entities_Global\Common_Table; 23 24 24 25 if ( ! class_exists( 'WP_List_Table' ) ) { … … 164 165 $this->handle_table_actions(); 165 166 166 $items = $this->fetch_table_data(); 167 global $wpdb; 168 169 $per_page = self::get_screen_option_per_page(); 170 171 $current_page = $this->get_pagenum(); 172 if ( 1 < $current_page ) { 173 $offset = $per_page * ( $current_page - 1 ); 174 } else { 175 $offset = 0; 176 } 177 178 $search_string = self::escaped_search_input(); 179 180 $wpdb_table = $this->get_table_name(); 181 182 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : self::$table::get_real_id_name(); 183 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'ASC'; 184 185 $items = $this->fetch_table_data( 186 array( 187 'search_string' => self::escaped_search_input(), 188 'offset' => $offset, 189 'per_page' => $per_page, 190 'wpdb_table' => $wpdb_table, 191 'orderby' => $orderby, 192 'order' => $order, 193 ) 194 ); 167 195 168 196 $columns = self::$table::manage_columns( array() ); … … 209 237 * @return array 210 238 */ 211 p rotectedfunction get_sortable_columns() {239 public function get_sortable_columns() { 212 240 $first6_columns = array_keys( self::$table::get_column_names_admin() ); 213 241 … … 239 267 * Fetch table data from the WordPress database. 240 268 * 269 * @param array $args - The arguments collected / passed. 270 * 241 271 * @since 1.0.0 272 * @since latest - added $args param. 242 273 * 243 274 * @return Array 244 275 */ 245 public function fetch_table_data( ) {276 public function fetch_table_data( array $args = array() ) { 246 277 247 278 global $wpdb; 248 279 249 $per_page = self::get_screen_option_per_page(); 250 251 $current_page = $this->get_pagenum(); 252 if ( 1 < $current_page ) { 253 $offset = $per_page * ( $current_page - 1 ); 254 } else { 255 $offset = 0; 256 } 257 258 $search_string = self::escaped_search_input(); 280 // Parse. 281 $parsed_args = \wp_parse_args( 282 $args, 283 array( 284 'offset' => 0, 285 'search_string' => self::escaped_search_input(), 286 'per_page' => self::get_screen_option_per_page(), 287 'wpdb_table' => $this->get_table_name(), 288 'orderby' => self::$table::get_real_id_name(), 289 'order' => 'DESC', 290 'count' => false, 291 ) 292 ); 293 294 $search_string = $parsed_args['search_string']; 295 $offset = $parsed_args['offset']; 296 $per_page = $parsed_args['per_page']; 297 $wpdb_table = $parsed_args['wpdb_table']; 298 $orderby = $parsed_args['orderby']; 299 $order = $parsed_args['order']; 259 300 260 301 $search_sql = ''; … … 268 309 } 269 310 270 $wpdb_table = $this->get_table_name(); 271 272 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : self::$table::get_real_id_name(); 273 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'ASC'; 274 $query = 'SELECT 311 $query = 'SELECT 275 312 ' . implode( ', ', self::$table::get_column_names() ) . ' 276 313 FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order; … … 279 316 280 317 // query output_type will be an associative array with ARRAY_A. 281 $query_results = $wpdb->get_results( $query, ARRAY_A ); 282 283 $this->count = (int) $wpdb->get_var( 'SELECT COUNT(' . self::$table::get_real_id_name() . ') FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql ); 318 $query_results = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 319 320 $this->count = (int) $wpdb->get_var( 'SELECT COUNT(' . self::$table::get_real_id_name() . ') FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 284 321 285 322 // return result array to prepare_items. … … 585 622 586 623 </div> 587 588 624 <?php 625 if ( 'top' === $which && $this->count > 0 ) { 626 ?> 627 <div id="export-form"> 628 <div> 629 <button id="start-export" class="button" data-type-export="table" data-table-name="<?php echo \esc_attr( self::$table::get_name() ); ?>" data-search="<?php echo \esc_attr( self::escaped_search_input() ); ?>"> 630 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 631 </button> 632 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 633 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 634 </button> 635 </div> 636 637 <div id="progress-container" class="progress-wrap" style="display:none;"> 638 <div id="progress-bar"></div> 639 </div> 640 641 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 642 </div> 643 644 <?php 645 } 589 646 // if ( 'top' === $which ) { 590 647 global $wpdb; 591 648 ?> 592 <script> 593 jQuery('form .table_filter').on('change', function(e) { 594 jQuery('form .table_filter').val(jQuery(this).val()); 595 jQuery( this ).closest( 'form' ).attr( 'action', '<?php echo \esc_url( \admin_url( 'admin-post.php' ) ); ?>').append('<input type="hidden" name="action" value="<?php echo \esc_attr( self::SWITCH_ACTION ); ?>">').append('<?php \wp_nonce_field( self::SWITCH_ACTION, self::SWITCH_ACTION . 'nonce' ); ?>').submit(); 596 }); 597 </script> 649 <script> 650 jQuery('form .table_filter').on('change', function(e) { 651 jQuery('form .table_filter').val(jQuery(this).val()); 652 jQuery( this ).closest( 'form' ).attr( 'action', '<?php echo \esc_url( \admin_url( 'admin-post.php' ) ); ?>').append('<input type="hidden" name="action" value="<?php echo \esc_attr( self::SWITCH_ACTION ); ?>">').append('<?php \wp_nonce_field( self::SWITCH_ACTION, self::SWITCH_ACTION . 'nonce' ); ?>').submit(); 653 }); 654 655 function makeSearchableDropdown(selectEl) { 656 selectEl.style.display = "none"; 657 658 const container = document.createElement("div"); 659 container.className = "dropdown-container"; 660 661 const input = document.createElement("input"); 662 input.className = "dropdown-search"; 663 input.placeholder = "<?php \esc_html_e( 'Search tables...', '0-day-analytics' ); ?>"; 664 input.type = "search"; 665 input.style.fontFamily = "dashicons"; 666 667 const clearBtn = document.createElement("button"); 668 clearBtn.className = "clear-btn"; 669 clearBtn.type = "button"; 670 //clearBtn.textContent = "✕"; 671 672 const list = document.createElement("div"); 673 list.className = "dropdown-list"; 674 675 container.appendChild(input); 676 container.appendChild(clearBtn); 677 container.appendChild(list); 678 selectEl.parentNode.insertBefore(container, selectEl.nextSibling); 679 680 const options = Array.from(selectEl.options); 681 let filteredOptions = options; 682 let activeIndex = -1; 683 684 // --- Measure dropdown width based on longest option --- 685 const measurer = document.createElement("span"); 686 measurer.className = "text-measurer"; 687 document.body.appendChild(measurer); 688 measurer.style.font = getComputedStyle(input).font; 689 690 let maxWidth = 0; 691 options.forEach(opt => { 692 measurer.textContent = opt.text; 693 maxWidth = Math.max(maxWidth, measurer.offsetWidth); 694 }); 695 measurer.remove(); 696 697 const inputWidth = input.offsetWidth; 698 const dropdownWidth = Math.max(maxWidth + 30, inputWidth); 699 list.style.width = dropdownWidth + "px"; 700 701 // --- Fill input with current selected value --- 702 const selectedOption = selectEl.options[selectEl.selectedIndex]; 703 if (selectedOption && selectedOption.text) { 704 input.value = selectedOption.text; 705 clearBtn.style.display = "block"; 706 } 707 708 // --- Clear button logic --- 709 clearBtn.addEventListener("click", () => { 710 input.value = ""; 711 // selectEl.value = ""; 712 clearBtn.style.display = "none"; 713 // const event = new Event("change", { bubbles: true }); 714 // selectEl.dispatchEvent(event); 715 renderList(""); 716 input.focus(); 717 }); 718 719 // --- Rendering dropdown list --- 720 function renderList(filter = "") { 721 list.innerHTML = ""; 722 filteredOptions = options.filter(opt => 723 opt.text.toLowerCase().includes(filter.toLowerCase()) 724 ); 725 726 filteredOptions.forEach((opt, i) => { 727 const item = document.createElement("div"); 728 item.textContent = opt.text; 729 item.className = "dropdown-item"; 730 if (i === activeIndex) item.classList.add("active"); 731 item.addEventListener("mousedown", e => { 732 e.preventDefault(); 733 selectOption(opt); 734 }); 735 list.appendChild(item); 736 }); 737 738 list.style.display = filteredOptions.length ? "block" : "none"; 739 if (activeIndex >= 0) scrollActiveIntoView(); 740 } 741 742 // --- Handle selection --- 743 function selectOption(opt) { 744 input.value = opt.text; 745 selectEl.value = opt.value; 746 list.style.display = "none"; 747 clearBtn.style.display = opt.value ? "block" : "none"; 748 input.focus(); 749 const event = new Event("change", { bubbles: true }); 750 selectEl.dispatchEvent(event); 751 } 752 753 function moveActive(delta) { 754 if (!filteredOptions.length) return; 755 activeIndex = (activeIndex + delta + filteredOptions.length) % filteredOptions.length; 756 renderList(input.value); 757 } 758 759 function scrollActiveIntoView() { 760 const activeItem = list.querySelector(".active"); 761 if (activeItem) { 762 const listRect = list.getBoundingClientRect(); 763 const itemRect = activeItem.getBoundingClientRect(); 764 if (itemRect.bottom > listRect.bottom) { 765 list.scrollTop += itemRect.bottom - listRect.bottom; 766 } else if (itemRect.top < listRect.top) { 767 list.scrollTop -= listRect.top - itemRect.top; 768 } 769 } 770 } 771 772 // --- Input events --- 773 input.addEventListener("input", e => { 774 activeIndex = -1; 775 renderList(e.target.value); 776 clearBtn.style.display = e.target.value ? "block" : "none"; 777 }); 778 779 input.addEventListener("focus", () => { 780 activeIndex = -1; 781 renderList(input.value); 782 }); 783 784 input.addEventListener("keydown", e => { 785 if (list.style.display === "none" && !["ArrowDown", "ArrowUp"].includes(e.key)) return; 786 switch (e.key) { 787 case "ArrowDown": 788 e.preventDefault(); 789 moveActive(1); 790 break; 791 case "ArrowUp": 792 e.preventDefault(); 793 moveActive(-1); 794 break; 795 case "Enter": 796 e.preventDefault(); 797 if (activeIndex >= 0 && filteredOptions[activeIndex]) { 798 selectOption(filteredOptions[activeIndex]); 799 } 800 break; 801 case "Escape": 802 list.style.display = "none"; 803 break; 804 } 805 }); 806 807 document.addEventListener("click", e => { 808 if (!container.contains(e.target)) list.style.display = "none"; 809 }); 810 } 811 812 // --- Initialize --- 813 makeSearchableDropdown(document.getElementById("table_filter_<?php echo \esc_attr( $which ); ?>")); 814 815 </script> 598 816 <?php 599 817 if ( 'top' === $which ) { 600 818 ?> 601 819 <style> 602 .flex { 603 display:flex; 604 } 605 .flex-row { 606 flex-direction:row; 607 } 608 .grow-0 { 609 flex-grow:0; 610 } 611 .p-2 { 612 padding:8px; 613 } 614 .w-full { 615 width:auto; 616 } 617 .border-t { 618 border-bottom-width:1px; 619 } 620 .justify-between { 621 justify-content:space-between; 622 } 623 .italic { 624 font-style: italic; 625 } 626 .text-lg { 627 font-size: 1.1em; 628 font-weight: bold; 629 } 630 #wpwrap { 631 overflow-x: hidden !important; 632 } 633 .wp-list-table { 634 white-space: nowrap; 635 display: block; 636 overflow-x: auto; 637 } 820 <?php echo Miscellaneous::get_flex_style(); ?> 638 821 /* .wp-list-table { 639 822 display: block; … … 650 833 top: 0; 651 834 } */ 652 653 </style> 835 .dropdown-container { 836 position: relative; 837 display: inline-block; 838 font-family: dashicons; 839 } 840 841 .dropdown-search { 842 width: 200px; /* fixed input width */ 843 box-sizing: border-box; 844 padding: 6px 28px 6px 6px; /* space for clear button */ 845 font-size: 14px; 846 } 847 848 /* 🔘 Clear button styling */ 849 .clear-btn { 850 position: absolute; 851 right: 6px; 852 top: 50%; 853 transform: translateY(-50%); 854 width: 18px; 855 height: 18px; 856 border: 1px solid #ccc; 857 border-radius: 50%; 858 background: white; 859 color: #666; 860 font-size: 12px; 861 font-weight: bold; 862 line-height: 1; 863 text-align: center; 864 cursor: pointer; 865 display: none; 866 padding: 0; 867 box-shadow: 0 1px 2px rgba(0,0,0,0.1); 868 } 869 870 .clear-btn:hover { 871 background: #f2f2f2; 872 color: #000; 873 border-color: #999; 874 } 875 876 .clear-btn::before { 877 content: "✕"; 878 top: -3px; 879 position: relative; 880 font-size: 0.7em; 881 color: #9e9898; 882 } 883 884 .dropdown-list { 885 position: absolute; 886 top: 100%; 887 left: 0; 888 border: 1px solid #ccc; 889 border-top: none; 890 max-height: 150px; 891 overflow-y: auto; 892 background: #fff; 893 display: none; 894 z-index: 100; 895 min-width: 100%; 896 } 897 898 .dropdown-item { 899 padding: 6px; 900 cursor: pointer; 901 white-space: nowrap; 902 } 903 904 .dropdown-item:hover, 905 .dropdown-item.active { 906 background-color: #0078d4; 907 color: #fff; 908 } 909 910 .text-measurer { 911 position: absolute; 912 visibility: hidden; 913 white-space: nowrap; 914 font-size: 14px; 915 font-family: sans-serif; 916 left: -9999px; 917 top: -9999px; 918 } 919 </style> 654 920 <?php } ?> 655 921 <div class="flex flex-row grow-0 p-2 w-full border-0 border-t border-solid justify-between"> -
0-day-analytics/tags/3.8.0/classes/vendor/lists/class-transients-list.php
r3375318 r3380967 19 19 use ADVAN\Helpers\WP_Helper; 20 20 use ADVAN\Helpers\Crons_Helper; 21 use ADVAN\Helpers\Miscellaneous; 21 22 use ADVAN\Lists\Traits\List_Trait; 22 23 use ADVAN\Helpers\Transients_Helper; … … 276 277 $this->fetch_table_data( 277 278 array( 278 'search' => $search,279 'offset' => $offset,280 ' number'=> $per_page,281 'orderby' => $orderby,282 'order' => $order,283 'type' => $type,279 'search' => $search, 280 'offset' => $offset, 281 'per_page' => $per_page, 282 'orderby' => $orderby, 283 'order' => $order, 284 'type' => $type, 284 285 ) 285 286 ); … … 327 328 * @return array 328 329 */ 329 p rotectedfunction get_sortable_columns() {330 public function get_sortable_columns() { 330 331 // Currently there is no way to implement sorting because of the way they are stored in the database. 331 332 return array( … … 377 378 $args, 378 379 array( 379 'offset' => 0,380 ' number' => self::get_screen_option_per_page(),381 'search' => '',382 'count' => false,380 'offset' => 0, 381 'per_page' => self::get_screen_option_per_page(), 382 'search' => '', 383 'count' => false, 383 384 ) 384 385 ); … … 451 452 452 453 $actions['delete'] = '<a class="aadvana-transient-delete" href="#" data-nonce="' . $query_args_view_data['_wpnonce'] . '" data-id="' . $query_args_view_data['hash'] . '">' . \esc_html__( 'Delete', '0-day-analytics' ) . '</a>'; 454 455 $actions['view'] = '<a class="aadvana-tablerow-view" href="#" data-details-id="' . $query_args_view_data['hash'] . '">' . \esc_html__( 'View', '0-day-analytics' ) . '</a>'; 453 456 454 457 $edit_url = \remove_query_arg( … … 591 594 592 595 ?> 593 <script>594 window.location.href = '<?php echo $redirect; ?>';595 </script>596 <script> 597 window.location.href = '<?php echo \esc_url_raw( $redirect ); ?>'; 598 </script> 596 599 <?php 597 600 } … … 689 692 </script> 690 693 <style> 694 <?php echo Miscellaneous::get_flex_style(); ?> 691 695 .generated-transients .persistent th:nth-child(1) { 692 696 border-left: 7px solid #d2ab0e !important; … … 711 715 } 712 716 $this->extra_tablenav( $which ); 717 if ( 'top' === $which && $this->count > 0 ) { 718 ?> 719 <div id="export-form"> 720 <div> 721 <button id="start-export" class="button" data-type-export="transients" data-transient-type="<?php echo isset( $_GET['event_type'] ) ? \esc_attr( \sanitize_text_field( \wp_unslash( $_GET['event_type'] ) ) ) : 'all'; ?>" data-search="<?php echo self::escaped_search_input(); ?>"> 722 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 723 </button> 724 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 725 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 726 </button> 727 </div> 728 729 <div id="progress-container" class="progress-wrap" style="display:none;"> 730 <div id="progress-bar"></div> 731 </div> 732 733 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 734 </div> 735 736 <?php 737 } 738 713 739 $this->pagination( $which ); 714 740 … … 772 798 * @since 1.4.0 773 799 */ 774 p rotectedfunction get_table_classes() {800 public function get_table_classes() { 775 801 return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] ); 776 802 } -
0-day-analytics/tags/3.8.0/classes/vendor/lists/class-wp-mail-list.php
r3378902 r3380967 21 21 use ADVAN\Controllers\WP_Mail_Log; 22 22 use ADVAN\Entities\WP_Mail_Entity; 23 use ADVAN\Helpers\Miscellaneous; 23 24 use ADVAN\Lists\Traits\List_Trait; 24 25 use ADVAN\Lists\Views\WP_Mail_View; … … 249 250 $items = $this->fetch_table_data( 250 251 array( 251 'search' => $search,252 'offset' => $offset,253 ' number'=> $per_page,254 'orderby' => $orderby,255 'order' => $order,256 'type' => $type,257 'site_id' => $site_id,252 'search' => $search, 253 'offset' => $offset, 254 'per_page' => $per_page, 255 'orderby' => $orderby, 256 'order' => $order, 257 'type' => $type, 258 'site_id' => $site_id, 258 259 ) 259 260 ); … … 346 347 $args, 347 348 array( 348 'offset' => 0,349 ' number'=> self::get_screen_option_per_page(),350 'search' => '',351 'orderby' => 'id',352 'order' => 'DESC',353 'count' => false,354 'site_id' => 0,349 'offset' => 0, 350 'per_page' => self::get_screen_option_per_page(), 351 'search' => '', 352 'orderby' => 'id', 353 'order' => 'DESC', 354 'count' => false, 355 'site_id' => 0, 355 356 ) 356 357 ); … … 368 369 if ( ! isset( $parsed_args['all'] ) ) { 369 370 370 $per_page = $parsed_args[' number'];371 $per_page = $parsed_args['per_page']; 371 372 $offset = $parsed_args['offset']; 372 373 … … 383 384 if ( '' !== $search_string ) { 384 385 $search_sql = 'AND (id LIKE "%' . $wpdb->esc_like( $search_string ) . '%"'; 385 foreach ( array_keys( WP_Mail_Entity::get_ column_names_admin() ) as $value ) {386 foreach ( array_keys( WP_Mail_Entity::get_all_columns() ) as $value ) { 386 387 $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" '; 387 388 } … … 1093 1094 <?php 1094 1095 } 1096 if ( 'top' === $which && count( $this->items )> 0) { 1097 ?> 1098 <div id="export-form"> 1099 <div> 1100 <button id="start-export" class="button" data-type-export="mail" data-search="<?php echo self::escaped_search_input(); ?>"> 1101 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 1102 </button> 1103 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 1104 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 1105 </button> 1106 </div> 1107 1108 <div id="progress-container" class="progress-wrap" style="display:none;"> 1109 <div id="progress-bar"></div> 1110 </div> 1111 1112 <p id="progress-text" style="display:none;"><?php echo \esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 1113 </div> 1114 1115 <?php 1116 } 1095 1117 if ( 'top' === $which ) { 1096 1118 ?> 1097 1119 <style> 1098 .flex { 1099 display:flex; 1100 } 1101 .flex-row { 1102 flex-direction:row; 1103 } 1104 .grow-0 { 1105 flex-grow:0; 1106 } 1107 .p-2 { 1108 padding:8px; 1109 } 1110 .w-full { 1111 width:auto; 1112 } 1113 .border-t { 1114 border-bottom-width:1px; 1115 } 1116 .justify-between { 1117 justify-content:space-between; 1118 } 1119 .italic { 1120 font-style: italic; 1121 } 1122 .text-lg { 1123 font-size: 1.1em; 1124 font-weight: bold; 1125 } 1126 #wpwrap { 1127 overflow-x: hidden !important; 1128 } 1129 .wp-list-table { 1130 white-space: nowrap; 1131 display: block; 1132 overflow-x: auto; 1133 } 1120 <?php echo Miscellaneous::get_flex_style(); ?> 1134 1121 /* .wp-list-table { 1135 1122 display: block; -
0-day-analytics/tags/3.8.0/classes/vendor/lists/entity/class-common-table.php
r3378902 r3380967 996 996 $wpdb->suppress_errors( true ); 997 997 998 $results = $wpdb->get_results( $query, \ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 998 $results = $wpdb->get_results( $query, \ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 999 999 1000 1000 if ( '' !== $wpdb->last_error || null === $results ) { … … 1066 1066 * @since latest 1067 1067 */ 1068 p rivatestatic function format_value_for_html( $value ) {1068 public static function format_value_for_html( $value ) { 1069 1069 // Try to decode JSON if it's a string. 1070 1070 if ( is_string( $value ) ) { … … 1096 1096 $formatted = '<em>null</em>'; 1097 1097 } elseif ( is_numeric( $value ) ) { 1098 $formatted = esc_html( (string) $value );1098 $formatted = \esc_html( (string) $value ); 1099 1099 } else { 1100 1100 // Fallback to escaped plain string. 1101 $formatted = esc_html( (string) $value );1101 $formatted = \esc_html( (string) $value ); 1102 1102 } 1103 1103 -
0-day-analytics/tags/3.8.0/classes/vendor/lists/traits/class-list-trait.php
r3374674 r3380967 193 193 } 194 194 } 195 196 /** 197 * Returns the value of all of the records 198 * 199 * @return int 200 * 201 * @since latest 202 */ 203 public function get_count() { 204 return $this->count; 205 } 195 206 } 196 207 } -
0-day-analytics/tags/3.8.0/classes/vendor/lists/views/class-requests-view.php
r3375967 r3380967 67 67 ? absint( $_REQUEST['trans_id'] ) 68 68 : 0; 69 $transient = Transients_Helper::get_transient_by_id( $transient_id );69 $transient = Transients_Helper::get_transient_by_id( null, $transient_id ); 70 70 $name = Transients_Helper::get_transient_name( $transient['option_name'] ); 71 71 $expiration = Transients_Helper::get_transient_expiration_time( $transient['option_name'] ); -
0-day-analytics/tags/3.8.0/classes/vendor/lists/views/class-table-view.php
r3377720 r3380967 208 208 <p> 209 209 <b><?php \esc_html_e( 'Table', '0-day-analytics' ); ?>:</b> 210 <span class="table-name"><?php echo \esc_html( $table_name); ?></span><br>210 <span class="table-name"><?php echo \esc_html( $table_name ); ?></span><br> 211 211 </p> 212 212 <div class="aadvana-panel-wrapper"> … … 217 217 <h3><?php \esc_html_e( 'Row data:', '0-day-analytics' ); ?></h3> 218 218 </div> 219 <div class=""><span title="<?php echo __( 'Copy to clipboard (as raw HTML)', '0-day-analytics' ); ?>" class="dashicons dashicons-clipboard" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span> <span title="<?php esc_html_e( 'Share', '0-day-analytics' ); ?>" class="dashicons dashicons-share" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span></div>219 <div class=""><span title="<?php \esc_html_e( 'Copy to clipboard (as raw HTML)', '0-day-analytics' ); ?>" class="dashicons dashicons-clipboard" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span> <span title="<?php esc_html_e( 'Share', '0-day-analytics' ); ?>" class="dashicons dashicons-share" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span></div> 220 220 </div> 221 221 <div class="http-request-args aadvana-pre-300" style="background: #fff;color:#000;"> … … 244 244 try { 245 245 attResp = wp.apiFetch({ 246 path: '/<?php echo Endpoints::ENDPOINT_ROOT_NAME; ?>/v1/get_table_record/<?php echo $table_name?>/' + id + '/',246 path: '/<?php echo \esc_attr( Endpoints::ENDPOINT_ROOT_NAME ); ?>/v1/get_table_record/<?php echo \esc_attr( $table_name ); ?>/' + id + '/', 247 247 method: 'GET', 248 248 cache: 'no-cache' … … 273 273 274 274 jQuery(document).on('click', '.media-modal-close', function () { 275 jQuery('.media-modal .http-request-args').html('<?php \esc_html_e( 'Loading please wait...', '0-day-analytics' ); ?>');275 jQuery('.media-modal .http-request-args').html('<?php \esc_html_e( 'Loading please wait...', '0-day-analytics' ); ?>'); 276 276 //jQuery('.media-modal .table-name').html(''); 277 277 jQuery('.media-modal').removeClass('open'); … … 283 283 if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) { 284 284 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 285 286 console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())287 285 288 286 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); -
0-day-analytics/tags/3.8.0/classes/vendor/lists/views/class-transients-view.php
r3374674 r3380967 16 16 use ADVAN\Helpers\WP_Helper; 17 17 use ADVAN\Lists\Transients_List; 18 use ADVAN\ControllersApi\Endpoints; 18 19 use ADVAN\Helpers\Transients_Helper; 19 20 … … 40 41 public static function analytics_transients_page() { 41 42 \wp_enqueue_script( 'wp-api-fetch' ); 43 \wp_enqueue_style( 'media-views' ); 44 \wp_enqueue_script( 'wp-api-fetch' ); 42 45 ?> 43 46 <script> … … 62 65 ? absint( $_REQUEST['trans_id'] ) 63 66 : 0; 64 $transient = Transients_Helper::get_transient_by_id( $transient_id );67 $transient = Transients_Helper::get_transient_by_id( null, $transient_id ); 65 68 66 69 if ( null !== $transient ) { … … 72 75 73 76 $next_run_gmt = gmdate( 'Y-m-d H:i:s', $expiration ); 74 $next_run_date_local = get_date_from_gmt( $next_run_gmt, 'Y-m-d' );75 $next_run_time_local = get_date_from_gmt( $next_run_gmt, 'H:i:s' );77 $next_run_date_local = \get_date_from_gmt( $next_run_gmt, 'Y-m-d' ); 78 $next_run_time_local = \get_date_from_gmt( $next_run_gmt, 'H:i:s' ); 76 79 } 77 80 } … … 285 288 </form> 286 289 </div> 290 291 <style> 292 /* modal */ 293 .media-modal, 294 .media-modal-backdrop { 295 display: none; 296 } 297 298 .media-modal.open, 299 .media-modal-backdrop.open { 300 display: block; 301 } 302 303 #aadvana-modal.aadvana-modal .media-frame-title, 304 #aadvana-modal.aadvana-modal .media-frame-content { 305 left: 0; 306 } 307 308 .media-frame-router { 309 left: 10px; 310 } 311 #aadvana-modal.aadvana-modal 312 .media-frame-content { 313 top: 48px; 314 bottom: 0; 315 overflow: auto; 316 } 317 318 .button-link.media-modal-close { 319 cursor: pointer; 320 text-decoration: none; 321 } 322 323 .aadvana-modal-buttons{ 324 position: absolute; 325 top: 0; 326 right: 0; 327 } 328 .aadvana-modal-buttons .media-modal-close{ 329 position: relative; 330 width: auto; 331 padding: 0 .5rem; 332 } 333 334 .media-modal-close.prev .media-modal-icon::before { 335 content: "\f342"; 336 } 337 338 .media-modal-close.next .media-modal-icon::before { 339 content: "\f346"; 340 } 341 342 .modal-content-wrap { 343 padding: 16px; 344 } 345 346 /* tab and panel */ 347 .aadvana-modal .nav-tab-active{ 348 border-bottom: solid 1px white; 349 background-color: white; 350 } 351 .aadvana-panel-active{ 352 display:block; 353 margin: 1rem 0; 354 } 355 356 .wrapper { 357 text-align: center; 358 } 359 .wrapper .box{ 360 text-align: left; 361 background-color: #f4f5f6; 362 padding: .5rem; 363 border-radius: .5rem; 364 margin-bottom: 1rem; 365 display: inline-block; 366 vertical-align: top; 367 box-sizing: border-box; 368 } 369 html.aadvana-darkskin .wrapper .box { 370 background-color: #1d456b !important; 371 border: 1px solid #ccc; 372 } 373 html.aadvana-darkskin .media-frame-content { 374 background-color: #1d456b !important; 375 } 376 .wrapper #mail-body { 377 width: 99%; 378 } 379 @media screen and (max-width: 782px) { 380 381 .wrapper .box{ 382 display: block; 383 width: auto; 384 } 385 } 386 387 </style> 388 389 <div id="aadvana-modal" class="media-modal aadvana-modal"> 390 <div class="aadvana-modal-buttons"> 391 <button class="button-link media-modal-close"><span class="media-modal-icon"></span></button> 392 </div> 393 <div class="media-modal-content"> 394 <div class="media-frame"> 395 <div class="media-frame-title"> 396 <h1><?php \esc_html_e( 'Transient details:', '0-day-analytics' ); ?></h1> 397 </div> 398 <div class="media-frame-content"> 399 <div class="modal-content-wrap"> 400 <p> 401 <b><?php \esc_html_e( 'Transient', '0-day-analytics' ); ?>:</b> 402 <span class="transient-name"></span><br> 403 </p> 404 <div class="aadvana-panel-wrapper"> 405 <div class="aadvana-request-response aadvana-panel-active wrapper"> 406 <div class="box" id="mail-body"> 407 <div class="flex flex-row grow-0 p-2 w-full border-0 border-t border-solid justify-between"> 408 <div> 409 <h3><?php \esc_html_e( 'Transient data:', '0-day-analytics' ); ?></h3> 410 </div> 411 <div class=""><span title="<?php \esc_html_e( 'Copy to clipboard (as raw HTML)', '0-day-analytics' ); ?>" class="dashicons dashicons-clipboard" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span> <span title="<?php esc_html_e( 'Share', '0-day-analytics' ); ?>" class="dashicons dashicons-share" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span></div> 412 </div> 413 <div class="http-request-args aadvana-pre-300" style="background: #fff;color:#000;"> 414 <?php 415 \esc_html_e( 'Loading please wait...', '0-day-analytics' ); 416 ?> 417 418 </div> 419 </div> 420 </div> 421 </div> 422 </div> 423 </div> 424 </div> 425 </div> 426 </div> 427 <div class="media-modal-backdrop"></div> 428 429 <script> 430 431 jQuery(document).on('click', '.aadvana-tablerow-view', function( e ) { 432 e.preventDefault(); 433 let id = jQuery( this ).data( 'details-id' ); 434 let that = this; 435 var encodedValue = jQuery('<div />').text(id).html(); 436 try { 437 attResp = wp.apiFetch({ 438 path: '/<?php echo \esc_attr( Endpoints::ENDPOINT_ROOT_NAME ); ?>/v1/get_transient_record/' + id + '/', 439 method: 'GET', 440 cache: 'no-cache' 441 }).then( ( attResp ) => { 442 443 jQuery('.media-modal .http-request-args').html(attResp.mail_body); 444 jQuery('.media-modal .transient-name').html(attResp.transient_name); 445 446 } ).catch( 447 ( error ) => { 448 if (error.message) { 449 jQuery(that).closest("tr").after('<tr><td style="overflow:hidden;" colspan="'+(jQuery(that).closest("tr").find("td").length+1)+'"><div class="error" style="background:#fff; color:#000;"> ' + error.message + '</div></td></tr>'); 450 } 451 } 452 ); 453 } catch (error) { 454 throw error; 455 } finally { 456 jQuery(that).css({ 457 "pointer-events": "", 458 "cursor": "" 459 }) 460 } 461 462 jQuery('.media-modal').addClass('open'); 463 jQuery('.media-modal-backdrop').addClass('open'); 464 }); 465 466 jQuery(document).on('click', '.media-modal-close', function () { 467 jQuery('.media-modal .http-request-args').html('<?php \esc_html_e( 'Loading please wait...', '0-day-analytics' ); ?>'); 468 jQuery('.media-modal .transient-name').html(''); 469 jQuery('.media-modal').removeClass('open'); 470 jQuery('.media-modal-backdrop').removeClass('open'); 471 }); 472 473 jQuery( document ).on( 'click', '.dashicons.dashicons-clipboard', function( e ) { 474 475 if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) { 476 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 477 478 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); 479 // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection 480 // selectedText = jQuery(selectedText).text(); 481 482 navigator.clipboard.writeText(selectedText); 483 } 484 485 }); 486 487 jQuery( document ).ready( function() { 488 489 if ( navigator.share ) { 490 491 jQuery( document ).on( 'click', '.dashicons.dashicons-share', function( e ) { 492 493 if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) { 494 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 495 496 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); 497 // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection 498 // selectedText = jQuery(selectedText).text(); 499 500 const shareData = { 501 text: selectedText + '\n\n' + "<?php echo \get_site_url(); ?>", 502 }; 503 504 try { 505 navigator.share(shareData); 506 } catch (err) { 507 jQuery(this).text( `Error: ${err}` ); 508 } 509 510 } 511 }); 512 513 } else { 514 jQuery( '.dashicons.dashicons-share' ).remove(); 515 } 516 }); 517 </script> 287 518 <?php 519 288 520 } 289 521 } -
0-day-analytics/tags/3.8.0/classes/vendor/lists/views/class-wp-mail-view.php
r3375967 r3380967 452 452 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 453 453 454 console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())455 456 454 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); 457 455 // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection -
0-day-analytics/tags/3.8.0/css/admin/style.css
r3378902 r3380967 2664 2664 html.aadvana-darkskin .wp-core-ui textarea:hover, 2665 2665 html.aadvana-darkskin .wp-core-ui textarea:focus, 2666 html.aadvana-darkskin .wp-core-ui textarea:active { 2666 html.aadvana-darkskin .wp-core-ui textarea:active, 2667 html.aadvana-darkskin .wp-core-ui .dropdown-item { 2667 2668 background-color: #062038; 2668 2669 border-color: #383a3f; -
0-day-analytics/tags/3.8.0/js/admin/aadvana-settings.js
r3357219 r3380967 242 242 ------------------------------------------------------------------------------------------ */ 243 243 $searchSettings = jQuery('#aadvana-panel-search'), 244 $searchList= jQuery('#aadvana-search-list');244 $searchList0 = jQuery('#aadvana-search-list'); 245 245 246 246 $searchSettings.on('keyup', function () { 247 247 var valThis = $searchSettings.val().toLowerCase(); 248 $searchList .html('');248 $searchList0.html(''); 249 249 250 250 if (valThis == '') { … … 265 265 thistextparentid = $thisparent.attr('id'); 266 266 267 $searchList .append('<li><a href="#" data-section="' + thistextid + '" data-url="' + thistextparentid + '"><strong>' + thistextparent + '</strong> / ' + thistext + '</a></li>');267 $searchList0.append('<li><a href="#" data-section="' + thistextid + '" data-url="' + thistextparentid + '"><strong>' + thistextparent + '</strong> / ' + thistext + '</a></li>'); 268 268 } 269 269 else { … … 274 274 }); 275 275 276 $searchList .on('click', 'a', function () {276 $searchList0.on('click', 'a', function () { 277 277 var $thisElem = jQuery(this), 278 278 tabId = $thisElem.data('url'), … … 292 292 293 293 if (!container.is(e.target) && container.has(e.target).length === 0) { 294 $searchList .html('');294 $searchList0.html(''); 295 295 $searchSettings.val(''); 296 296 jQuery('.highlights-search').removeClass('highlights-search'); -
0-day-analytics/tags/3.8.0/readme.txt
r3378902 r3380967 4 4 Tested up to: 6.8 5 5 Requires PHP: 7.4 6 Stable tag: 3. 7.66 Stable tag: 3.8.0 7 7 License: GPLv3 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-3.0.txt … … 96 96 The plugin auto-detects default error log location, usually WordPress defines that in `wp-config.php`. You can customize this path if needed - this is strongly recommended for security reasons, and don't worry - you can do it with one click from plugin settings. 97 97 98 = Note =99 Because of its extremely poor implementation and interfering with the proper WordPress workflow (debug log set, constant pollution of the log file, improper JS implementation etc.), *Log-IQ* plugin is automatically deactivated.100 101 98 == Screenshots == 102 99 … … 113 110 == Changelog == 114 111 112 = 3.8.0 = 113 Added CSV export functionality to the modules. Code optimizations. 114 115 115 = 3.7.6 = 116 116 Resolved bug with bulk actions thanks to @lucianwpwhite . UI improvements for mobile, implemented formatting in table view, based on the typo of the value. -
0-day-analytics/tags/3.8.0/vendor/composer/autoload_classmap.php
r3375967 r3380967 31 31 'ADVAN\\Helpers\\File_Helper' => $baseDir . '/classes/vendor/helpers/class-file-helper.php', 32 32 'ADVAN\\Helpers\\Log_Line_Parser' => $baseDir . '/classes/vendor/helpers/class-log-line-parser.php', 33 'ADVAN\\Helpers\\Miscellaneous' => $baseDir . '/classes/vendor/helpers/class-miscellaneous.php', 33 34 'ADVAN\\Helpers\\PHP_Helper' => $baseDir . '/classes/vendor/helpers/class-php-helper.php', 34 35 'ADVAN\\Helpers\\Plugin_Theme_Helper' => $baseDir . '/classes/vendor/helpers/class-plugin-theme-helper.php', -
0-day-analytics/tags/3.8.0/vendor/composer/autoload_static.php
r3375967 r3380967 46 46 'ADVAN\\Helpers\\File_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-file-helper.php', 47 47 'ADVAN\\Helpers\\Log_Line_Parser' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-log-line-parser.php', 48 'ADVAN\\Helpers\\Miscellaneous' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-miscellaneous.php', 48 49 'ADVAN\\Helpers\\PHP_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-php-helper.php', 49 50 'ADVAN\\Helpers\\Plugin_Theme_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-plugin-theme-helper.php', -
0-day-analytics/trunk/advanced-analytics.php
r3378902 r3380967 11 11 * Plugin Name: 0 Day Analytics 12 12 * Description: Take full control of error log, crons, transients, plugins, requests, mails and DB tables. 13 * Version: 3. 7.613 * Version: 3.8.0 14 14 * Author: Stoil Dobrev 15 15 * Author URI: https://github.com/sdobreff/ … … 37 37 // Constants. 38 38 if ( ! defined( 'ADVAN_VERSION' ) ) { 39 define( 'ADVAN_VERSION', '3. 7.6' );39 define( 'ADVAN_VERSION', '3.8.0' ); 40 40 define( 'ADVAN_TEXTDOMAIN', '0-day-analytics' ); 41 41 define( 'ADVAN_NAME', '0 Day Analytics' ); … … 129 129 \add_action( 'wp_mail_failed', array( WP_Error_Handler::class, 'on_mail_error' ), -1 ); 130 130 131 \add_action( 'plugin_loaded', 'advana_remove_plugins' );132 \add_action( 'network_plugin_loaded', 'advana_remove_plugins' );131 // \add_action( 'plugin_loaded', 'advana_remove_plugins' ); 132 // \add_action( 'network_plugin_loaded', 'advana_remove_plugins' ); 133 133 134 134 if ( ! WP_Helper::is_multisite() && \wp_is_recovery_mode() ) { … … 220 220 * Because of its extremely poor implementation, the log-iq plugin must be deactivated as it interferes very badly with the proper WP work. 221 221 */ 222 if ( false !== strpos( $plugin, 'log-iq' . DIRECTORY_SEPARATOR ) ) {223 \deactivate_plugins( $plugin, true, null );224 }222 // if ( false !== strpos( $plugin, 'log-iq' . DIRECTORY_SEPARATOR ) ) { 223 // \deactivate_plugins( $plugin, true, null ); 224 // } 225 225 } 226 226 } -
0-day-analytics/trunk/classes/vendor/controllers/class-endpoints.php
r3377720 r3380967 16 16 17 17 use ADVAN\Lists\Logs_List; 18 use ADVAN\Lists\WP_Mail_List; 18 19 use ADVAN\Lists\Requests_List; 20 use ADVAN\Helpers\Crons_Helper; 21 use ADVAN\Helpers\Transients_Helper; 19 22 use ADVAN\Entities_Global\Common_Table; 20 use ADVAN\Helpers\Crons_Helper;21 use ADVAN\Lists\WP_Mail_List;22 23 23 24 defined( 'ABSPATH' ) || exit; // Exit if accessed directly. … … 242 243 'pattern' => '.+', 243 244 'description' => 'ID of the table record which row needs to be shown', 245 ), 246 ), 247 'checkPermissions' => array( __CLASS__, 'check_permissions' ), 248 'showInIndex' => false, 249 ), 250 ), 251 ), 252 ), 253 'get_transient_record' => array( 254 'class' => Transients_Helper::class, 255 'namespace' => self::ENDPOINT_ROOT_NAME . '/v1', 256 257 'endpoints' => array( 258 array( 259 '(?P<transient_id>\w+)' => array( 260 'methods' => array( 261 'method' => \WP_REST_Server::READABLE, 262 'callback' => 'get_transient_by_id', 263 ), 264 'args' => array( 265 'transient_id' => array( 266 'required' => true, 267 'type' => 'string', 268 'pattern' => '\d+', 269 'description' => 'Transient hash', 244 270 ), 245 271 ), -
0-day-analytics/trunk/classes/vendor/entities/class-abstract-entity.php
r3375967 r3380967 770 770 return $results; 771 771 } 772 773 /** 774 * Returns all column names which belong to the table 775 * 776 * @return array 777 * 778 * @since latest 779 */ 780 public static function get_all_columns(): array { 781 return ( static::class )::$fields; 782 } 772 783 } 773 784 } -
0-day-analytics/trunk/classes/vendor/helpers/class-ajax-helper.php
r3377720 r3380967 12 12 namespace ADVAN\Helpers; 13 13 14 use ADVAN\Lists\Logs_List; 14 15 use ADVAN\Helpers\Settings; 16 use ADVAN\Lists\Crons_List; 17 use ADVAN\Lists\Table_List; 15 18 use ADVAN\Controllers\Slack; 16 19 use ADVAN\Helpers\WP_Helper; 20 use ADVAN\Lists\WP_Mail_List; 21 use ADVAN\Lists\Requests_List; 17 22 use ADVAN\Controllers\Telegram; 18 23 use ADVAN\Controllers\Error_Log; 24 use ADVAN\Controllers\Slack_API; 25 use ADVAN\Lists\Transients_List; 26 use ADVAN\Controllers\Telegram_API; 27 use ADVAN\Entities_Global\Common_Table; 19 28 use ADVAN\Controllers\Mail_SMTP_Settings; 20 use ADVAN\Controllers\Slack_API;21 use ADVAN\Controllers\Telegram_API;22 use ADVAN\Lists\Logs_List;23 29 24 30 // Exit if accessed directly. … … 141 147 142 148 \add_action( 'wp_ajax_advana_error_log_filtering_dismiss_notice', array( __CLASS__, 'error_log_filtering_dismiss_notice' ) ); 149 150 \add_action( 'wp_ajax_aadvana_export_large_csv', array( __CLASS__, 'export_large_csv' ) ); 151 \add_action( 'wp_ajax_aadvana_export_large_csv_cleanup', array( __CLASS__, 'export_large_csv_cleanup' ) ); 143 152 } 144 153 } … … 650 659 \wp_die(); 651 660 } 661 662 /** 663 * Export Large CSV in Batches 664 * 665 * @return void 666 * 667 * @since latest 668 */ 669 public static function export_large_csv() { 670 WP_Helper::verify_admin_nonce( 'export_large_csv_nonce', 'security' ); 671 672 $batch = isset( $_POST['batch'] ) ? intval( $_POST['batch'] ) : 0; 673 $batch_size = isset( $_POST['batch_size'] ) ? intval( $_POST['batch_size'] ) : 500; 674 $offset = $batch * $batch_size; 675 676 list($export_dir, $export_url) = Miscellaneous::get_export_dir(); 677 678 $csv_path = $export_dir . 'export_temp.csv'; 679 $csv_url = $export_url . 'export_temp.csv'; 680 681 $rows = array(); 682 $total = 0; 683 $extra_file_name = ''; 684 685 if ( isset( $_POST['typeExport'] ) && ! empty( $_POST['typeExport'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 686 if ( 'cron' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 687 $rows = Crons_List::get_cron_items(); 688 $rows = \array_slice( $rows, $offset, $batch_size, true ); 689 $total = count( $rows ); 690 } 691 if ( 'logs' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 692 693 $plugin_filter = ( ( isset( $_POST['plugin_filter'] ) ) ? \sanitize_text_field( \wp_unslash( $_POST['plugin_filter'] ) ) : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing 694 695 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 696 697 $extra_file_name = '_' . $plugin_filter . '_'; 698 699 $list_logs = new Logs_List( array( 'plugin_filter' => $plugin_filter ) ); 700 701 $rows = $list_logs::get_error_items(); 702 $rows = \array_slice( $rows, $offset, $batch_size, true ); 703 704 foreach ( $rows as $key => $row ) { 705 if ( isset( $row['sub_items'] ) ) { 706 if ( \is_array( $row['sub_items'] ) && ! empty( $row['sub_items'] ) ) { 707 $subs = array(); 708 foreach ( $row['sub_items'] as $sub_key => $sub_item ) { 709 $subs[] = \json_encode( $sub_item ); 710 } 711 712 $rows[ $key ]['sub_items'] = $subs; 713 } 714 } else { 715 $rows[ $key ]['sub_items'] = ''; 716 } 717 if ( !isset( $row['plugin'] ) ) { 718 $rows[ $key ]['plugin'] = ''; 719 } 720 } 721 722 $total = count( $rows ); 723 } 724 if ( 'table' === $_POST['typeExport'] && isset( $_POST['tableName'] ) && ! empty( $_POST['tableName'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 725 $table = \sanitize_text_field( \wp_unslash( $_POST['tableName'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing 726 727 $search = isset( $_POST['search'] ) ? \sanitize_text_field( \wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 728 729 $extra_file_name = '_' . str_replace( ' ', '_', $table ) . '_'; 730 if ( Common_Table::check_table_exists( $table ) ) { 731 $list_table = new Table_List( $table ); 732 733 $rows = $list_table->fetch_table_data( 734 array( 735 'per_page' => $batch_size, 736 'offset' => $offset, 737 'order' => 'ASC', 738 'search_string' => $search, 739 ) 740 ); 741 742 $total = $list_table->get_count(); 743 } 744 } 745 if ( 'mail' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 746 747 $list_table = new WP_Mail_List(); 748 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 749 $extra_file_name = '_' . str_replace( ' ', '_', $list_table->get_table_name() ) . '_'; 750 751 $rows = $list_table->fetch_table_data( 752 array( 753 'per_page' => $batch_size, 754 'offset' => $offset, 755 'order' => 'ASC', 756 'site_id' => '', 757 'search' => $search, 758 ) 759 ); 760 761 $total = $list_table->get_count(); 762 } 763 if ( 'requests' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 764 765 $list_table = new Requests_List(); 766 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 767 $plugin = isset( $_POST['plugin'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 768 $extra_file_name = '_' . str_replace( ' ', '_', $list_table->get_table_name() ) . '_'; 769 770 $rows = $list_table->fetch_table_data( 771 array( 772 'per_page' => $batch_size, 773 'offset' => $offset, 774 'order' => 'ASC', 775 'search_string' => $search, 776 'plugin' => $plugin, 777 ) 778 ); 779 780 $total = $list_table->get_count(); 781 } 782 if ( 'transients' === $_POST['typeExport'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing 783 784 $list_table = new Transients_List( array() ); 785 786 $type = isset( $_POST['transientType'] ) ? sanitize_text_field( wp_unslash( $_POST['transientType'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 787 788 $extra_file_name = '_' . str_replace( ' ', '_', $list_table->get_table_name() ) . '_' . $type . '_'; 789 790 $search = isset( $_POST['search'] ) ? sanitize_text_field( wp_unslash( $_POST['search'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing 791 792 $rows = $list_table->fetch_table_data( 793 array( 794 'per_page' => $batch_size, 795 'offset' => $offset, 796 'order' => 'ASC', 797 'type' => $type, 798 'search' => $search, 799 ) 800 ); 801 802 $total = $list_table->get_count(); 803 } 804 } else { 805 \wp_send_json_error( 806 array( 807 'message' => __( 'Export type is not specified.', '0-day-analytics' ), 808 ), 809 400 810 ); 811 } 812 813 if ( empty( $rows ) ) { 814 // Open CSV for writing/appending. 815 $handle = @fopen( $csv_path, $is_first_batch ? 'w' : 'a' ); 816 if ( ! $handle ) { 817 \wp_send_json_error( 818 array( 819 'message' => __( 'Failed to write to CSV file. Check folder permissions.', '0-day-analytics' ), 820 ), 821 500 822 ); 823 } 824 825 // Get date and time formats from WordPress settings. 826 $date_format = get_option( 'date_format' ); // e.g., 'F j, Y'. 827 $time_format = get_option( 'time_format' ); // e.g., 'g:i a'. 828 829 // Combine date and time if needed. 830 $formatted_datetime = date_i18n( $date_format . ' ' . $time_format ); 831 832 // Sanitize filename: replace spaces and colons with dashes. 833 $safe_datetime = preg_replace( '/[^A-Za-z0-9\-]/', '-', $formatted_datetime ); 834 835 // Create filename. 836 $filename = 'export_' . $_POST['typeExport'] . '_' . $extra_file_name . $safe_datetime . '.csv'; 837 838 rename( $export_dir . 'export_temp.csv', $export_dir . $filename ); // phpcs:ignore WordPress.WP.AlternativeFunctions.rename_rename 839 840 \wp_send_json_success( 841 array( 842 'done' => true, 843 'download_url' => $export_url . $filename, 844 ) 845 ); 846 } 847 848 $is_first_batch = ( 0 === $batch ); 849 850 // Open CSV for writing/appending. 851 $handle = @fopen( $csv_path, $is_first_batch ? 'w' : 'a' ); 852 if ( ! $handle ) { 853 \wp_send_json_error( 854 array( 855 'message' => __( 'Failed to write to CSV file. Check folder permissions.', '0-day-analytics' ), 856 ), 857 500 858 ); 859 } 860 861 if ( $is_first_batch && ! empty( $rows ) ) { 862 fputcsv( 863 $handle, 864 array_keys( reset( $rows ) ), 865 ',', 866 '"', 867 '\\', 868 ); 869 } 870 871 foreach ( $rows as $row ) { 872 \fputcsv( 873 $handle, 874 array_map( 875 function ( $value ): string { 876 // Convert to string. 877 if ( is_array( $value ) ) { 878 $value = \implode( ', ', $value ); 879 } 880 if ( is_object( $value ) ) { 881 $value = json_encode( $value ); 882 } 883 $value = (string) $value; 884 885 // Convert escaped sequences like \" \n \t into real .characters. 886 $value = stripcslashes( $value ); 887 888 // Remove control characters (non-printable). 889 $value = preg_replace( '/[\x00-\x1F\x7F]/u', '', $value ); 890 891 return (string) $value; 892 }, 893 $row 894 ), 895 ',', 896 '"', 897 '\\', 898 ); 899 } 900 901 fclose( $handle ); 902 903 \wp_send_json_success( 904 array( 905 'done' => false, 906 'next_batch' => $batch + 1, 907 'processed' => ( $batch + 1 ) * $batch_size, 908 'total' => $total, 909 ) 910 ); 911 } 912 913 /** 914 * Cleanup Temporary CSV 915 * 916 * @return void 917 * 918 * @since latest 919 */ 920 public static function export_large_csv_cleanup() { 921 WP_Helper::verify_admin_nonce( 'export_large_csv_nonce', 'security' ); 922 923 list($export_dir) = Miscellaneous::get_export_dir(); 924 925 $csv_path = $export_dir . 'export_temp.csv'; 926 927 if ( file_exists( $csv_path ) ) { 928 unlink( $csv_path ); 929 \wp_send_json_success( array( 'deleted' => true ) ); 930 } else { 931 \wp_send_json_success( array( 'deleted' => false ) ); 932 } 933 } 652 934 } 653 935 } -
0-day-analytics/trunk/classes/vendor/helpers/class-settings.php
r3374674 r3380967 306 306 'wp-api-fetch' 307 307 ); 308 309 // Exporting CSV start. 310 311 \wp_enqueue_style( 312 'oda-admin-export-style', 313 ADVAN_PLUGIN_ROOT_URL . 'css/admin-export-csv.css', 314 array(), 315 '1.1' 316 ); 317 318 \wp_enqueue_script( 319 'aadvana-admin-export-js', 320 ADVAN_PLUGIN_ROOT_URL . 'js/admin-export-csv.js', 321 array(), 322 '1.1', 323 true 324 ); 325 326 \wp_localize_script( 327 'aadvana-admin-export-js', 328 'aadvanaExport', 329 array( 330 'ajax_url' => admin_url( 'admin-ajax.php' ), 331 'nonce' => wp_create_nonce( 'export_large_csv_nonce' ), 332 'i18n' => array( 333 'starting' => __( 'Starting export...', '0-day-analytics' ), 334 'exporting' => __( 'Exporting...', '0-day-analytics' ), 335 'completed' => __( '✅ Export complete! Downloading...', '0-day-analytics' ), 336 'cancelled' => __( '❌ Export cancelled.', '0-day-analytics' ), 337 'networkError' => __( 'Network error', '0-day-analytics' ), 338 'error' => __( 'Error during export:', '0-day-analytics' ), 339 'unauthorized' => __( 'Unauthorized', '0-day-analytics' ), 340 'csvExportBtnTitle' => __( 'CSV Export', '0-day-analytics' ), 341 ), 342 ) 343 ); 344 // Exporting CSV end. 308 345 309 346 ?> -
0-day-analytics/trunk/classes/vendor/helpers/class-transients-helper.php
r3374674 r3380967 15 15 16 16 use ADVAN\Lists\Transients_List; 17 use ADVAN\Entities_Global\Common_Table; 17 18 18 19 // Exit if accessed directly. … … 148 149 * Retrieve a transient by its ID 149 150 * 150 * @param int $id - The ID of the transient to retrieve. 151 * @param \WP_REST_Request $request - The request object. 152 * @param int $id - The ID of the transient to retrieve. 151 153 * 152 154 * @return array 153 155 * 154 156 * @since 1.8.5 155 */ 156 public static function get_transient_by_id( $id = 0 ) { 157 * @since latest - Added $request parameter. 158 */ 159 public static function get_transient_by_id( ?\WP_REST_Request $request = null, $id = 0 ) { 157 160 global $wpdb; 158 161 … … 161 164 // Bail if empty ID. 162 165 if ( empty( $id ) ) { 163 return false; 166 if ( null !== $request ) { 167 $id = $request->get_param( 'transient_id' ); 168 } 169 if ( empty( $id ) ) { 170 return false; 171 } 164 172 } 165 173 … … 168 176 169 177 // Query. 170 return $wpdb->get_row( $prepared, ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared 178 $transient = $wpdb->get_row( $prepared, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 179 if ( null === $request ) { 180 return $transient; 181 } elseif ( ! empty( $transient ) ) { 182 \ob_start(); 183 184 $name = self::get_transient_name( $transient['option_name'] ); 185 186 if ( in_array( $name, self::WP_CORE_TRANSIENTS ) ) { 187 ?> 188 <div id="advaa-status-notice" class="notice notice-warning"> 189 <p><?php esc_html_e( 'This is a WP core transient', '0-day-analytics' ); ?></p> 190 </div> 191 <?php 192 } else { 193 foreach ( self::WP_CORE_TRANSIENTS as $trans_name ) { 194 if ( \str_starts_with( $name, $trans_name ) ) { 195 ?> 196 <div id="advaa-status-notice" class="notice notice-warning"> 197 <p><?php esc_html_e( 'This is a WP core transient, even if you update it, the new value will be overridden by the core!', '0-day-analytics' ); ?></p> 198 </div> 199 <?php 200 break; 201 } 202 } 203 } 204 ?> 205 <table class="widefat striped table-view-list" style="max-width:100%;table-layout: fixed;"> 206 <col width="20%" /> 207 <col width="80%" /> 208 <thead> 209 <tr> 210 <th> 211 <?php echo \esc_html_e( 'Name', '0-day-analytics' ); ?> 212 </th> 213 <th> 214 <?php echo \esc_html_e( 'Value', '0-day-analytics' ); ?> 215 </th> 216 </tr> 217 </thead> 218 <tbody> 219 <tr> 220 <th><?php esc_html_e( 'Option ID', '0-day-analytics' ); ?></th> 221 <td><?php echo esc_attr( $transient['option_id'] ); ?></td> 222 </tr> 223 <tr> 224 <th><?php \esc_html_e( 'Name', '0-day-analytics' ); ?></th> 225 <td><?php echo \esc_attr( self::clear_transient_name( $transient['option_name'] ) ); ?> 226 </tr> 227 <?php 228 $expiration = self::get_transient_expiration_time( $transient['option_name'] ); 229 if ( 0 !== $expiration ) { 230 231 $next_run_gmt = gmdate( 'Y-m-d H:i:s', $expiration ); 232 $next_run_date_local = \get_date_from_gmt( $next_run_gmt, 'Y-m-d' ); 233 $next_run_time_local = \get_date_from_gmt( $next_run_gmt, 'H:i:s' ); 234 } 235 if ( 0 !== $expiration ) { 236 ?> 237 <tr> 238 <th><?php \esc_html_e( 'Expiration', '0-day-analytics' ); ?></th> 239 <td> 240 <?php 241 echo \esc_attr( $next_run_date_local ) . ' ' . \esc_attr( $next_run_time_local ); 242 ?> 243 </td> 244 </tr> 245 <?php 246 } else { 247 248 } 249 250 ?> 251 <tr> 252 <th><?php esc_html_e( 'Value', '0-day-analytics' ); ?></th> 253 <td> 254 <?php echo Common_Table::format_value_for_html( $transient['option_value'] ); ?> 255 </td> 256 </tr> 257 </tbody> 258 </table> 259 <?php 260 $message = \ob_get_clean(); 261 262 return rest_ensure_response( 263 array( 264 'success' => true, 265 'mail_body' => $message, 266 'transient_name' => $name, 267 ) 268 ); 269 270 } else { 271 return new \WP_Error( 272 'empty_row', 273 __( 'No record found.', '0-day-analytics' ), 274 array( 'status' => 400 ) 275 ); 276 } 171 277 } 172 278 … … 334 440 $type = \esc_html__( 'json', '0-day-analytics' ); 335 441 } elseif ( is_string( $value ) && in_array( $value, array( 'no', 'yes', 'false', 'true' ), true ) ) { 336 $type = \esc_html__( 'boolean?', '0-day-analytics' );442 $type = \esc_html__( 'boolean?', '0-day-analytics' ); 337 443 338 444 // Scalar. … … 392 498 393 499 // Escape some LIKE parts. 394 $esc_name = '' . $wpdb->esc_like( '_transient_' ) . '%';500 $esc_name = '' . $wpdb->esc_like( '_transient_' ) . '%'; 395 501 $esc_site_name = '' . $wpdb->esc_like( '_site_transient_' ) . '%'; 396 $esc_time = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%';502 $esc_time = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%'; 397 503 398 504 // SELECT. … … 410 516 // if ( empty( $parsed_args['count'] ) ) { 411 517 412 // FROM.413 518 // FROM. 519 414 520 // old - ON d.option_name LIKE CONCAT('%_transient_timeout_', SUBSTRING_INDEX( go.option_name, '_transient_', -1 ), '%') 415 521 416 $sql[] = "LEFT JOIN522 $sql[] = "LEFT JOIN 417 523 {$wpdb->options} d 418 524 ON d.option_name = CONCAT( … … 456 562 if ( empty( $parsed_args['count'] ) && empty( $parsed_args['all'] ) ) { 457 563 $offset = absint( $parsed_args['offset'] ); 458 $ number = absint( $parsed_args['number'] );564 $per_page = absint( $parsed_args['per_page'] ); 459 565 460 566 // if ( ! empty( $parsed_args['orderby'] ) && \in_array( $parsed_args['orderby'], array( 'transient_name' ) ) ) { … … 475 581 // ); 476 582 // } else { 477 $sql[] = $wpdb->prepare( 'ORDER BY option_id DESC LIMIT %d, %d', $offset, $number);583 $sql[] = $wpdb->prepare( 'ORDER BY option_id DESC LIMIT %d, %d', $offset, $per_page ); 478 584 // } 479 585 } … … 487 593 // Query. 488 594 $transients = empty( $parsed_args['count'] ) 489 ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared490 : $wpdb->get_var( $prepared, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared595 ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 596 : $wpdb->get_var( $prepared, 0 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 491 597 492 598 if ( empty( $parsed_args['count'] ) && ! empty( $transients ) ) { … … 496 602 'transient_name' => self::get_transient_name( $transient['option_name'] ), 497 603 'value' => self::get_transient_value( $transient['option_value'] ), 498 'schedule' => (int) $transient['schedule'] ,604 'schedule' => (int) $transient['schedule'], 499 605 'id' => $transient['option_id'], 500 606 ); -
0-day-analytics/trunk/classes/vendor/lists/class-crons-list.php
r3378902 r3380967 352 352 * 353 353 * @since 1.1.0 354 * @since 2.9.0 - Introduced flag getting the events wi htout the type filtering354 * @since 2.9.0 - Introduced flag getting the events without the type filtering 355 355 */ 356 356 public static function get_cron_items( bool $no_type_filtering = false ): array { … … 926 926 </select> 927 927 <?php \submit_button( __( 'Filter', '0-day-analytics' ), '', 'filter_action', false, array( 'id' => 'schedules-submit' ) ); ?> 928 </div> 929 <div id="export-form"> 930 <div> 931 <button id="start-export" class="button" data-type-export="cron"> 932 <?php echo esc_html__( 'CSV Export', '0-day-analytics' ); ?> 933 </button> 934 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 935 <?php echo esc_html__( 'Cancel', '0-day-analytics' ); ?> 936 </button> 937 </div> 938 939 <div id="progress-container" class="progress-wrap" style="display:none;"> 940 <div id="progress-bar"></div> 941 </div> 942 943 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 928 944 </div> 929 945 <?php … … 1136 1152 return sprintf( 1137 1153 $format, 1138 esc_attr( $link ),1139 esc_html( $text ),1154 \esc_attr( $link ), 1155 \esc_html( $text ), 1140 1156 ( 'edit' ) 1141 1157 ); … … 1202 1218 * @since 1.4.0 1203 1219 */ 1204 p rotectedfunction get_table_classes() {1220 public function get_table_classes() { 1205 1221 return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] ); 1206 1222 } -
0-day-analytics/trunk/classes/vendor/lists/class-logs-list.php
r3377720 r3380967 1123 1123 <?php 1124 1124 } 1125 } 1126 if ( 'top' === $which && count(self::$items_collected) > 0 ) { 1127 ?> 1128 <div id="export-form" style="display:inline-block;"> 1129 <div> 1130 <button id="start-export" class="button" data-type-export="logs" data-search="<?php echo \esc_attr( self::escaped_search_input() ); ?>" data-plugin-filter="<?php echo ( isset( self::$query_args['plugin_filter'] ) ) ? \esc_attr( self::$query_args['plugin_filter'] ) : '-1'; ?>"> 1131 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 1132 </button> 1133 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 1134 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 1135 </button> 1136 </div> 1137 1138 <div id="progress-container" class="progress-wrap" style="display:none;"> 1139 <div id="progress-bar"></div> 1140 </div> 1141 1142 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 1143 </div> 1144 1145 <?php 1125 1146 } 1126 1147 ?> … … 1345 1366 </select> 1346 1367 </div> 1347 <?php 1348 $dismissed = \get_user_meta( \get_current_user_id(), '_aadvana_filter_error_log_notice_dismissed', true ); 1349 1350 if ( ! $dismissed ) { 1351 ?> 1368 <?php 1369 1370 $dismissed = \get_user_meta( \get_current_user_id(), '_aadvana_filter_error_log_notice_dismissed', true ); 1371 1372 if ( ! $dismissed ) { 1373 ?> 1352 1374 1353 1375 <div id="advaa-filtering-notice" class="notice notice-info is-dismissible"> … … 1367 1389 }); 1368 1390 </script> 1369 <?php1370 }1371 ?>1391 <?php 1392 } 1393 ?> 1372 1394 <script> 1373 1395 -
0-day-analytics/trunk/classes/vendor/lists/class-requests-list.php
r3375967 r3380967 18 18 use ADVAN\Helpers\WP_Helper; 19 19 use ADVAN\Helpers\File_Helper; 20 use ADVAN\ Entities_Global\Common_Table;20 use ADVAN\Helpers\Miscellaneous; 21 21 use ADVAN\Lists\Traits\List_Trait; 22 22 use ADVAN\ControllersApi\Endpoints; … … 24 24 use ADVAN\Helpers\Plugin_Theme_Helper; 25 25 use ADVAN\Entities\Requests_Log_Entity; 26 use ADVAN\Entities_Global\Common_Table; 26 27 27 28 if ( ! class_exists( 'WP_List_Table' ) ) { … … 207 208 $this->handle_table_actions(); 208 209 209 $items = $this->fetch_table_data(); 210 global $wpdb; 211 212 $per_page = self::get_screen_option_per_page(); 213 214 $current_page = $this->get_pagenum(); 215 if ( 1 < $current_page ) { 216 $offset = $per_page * ( $current_page - 1 ); 217 } else { 218 $offset = 0; 219 } 220 221 $search_string = self::escaped_search_input(); 222 223 if ( isset( $_REQUEST['plugin'] ) && ! empty( $_REQUEST['plugin'] ) ) { 224 if ( -1 === (int) $_REQUEST['plugin'] ) { 225 $plugin = -1; 226 } else { 227 $plugin = \sanitize_text_field( \wp_unslash( $_REQUEST['plugin'] ) ); 228 } 229 } else { 230 $plugin = ''; 231 } 232 233 $wpdb_table = $this->get_table_name(); 234 235 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : 'id'; 236 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'DESC'; 237 238 $items = $this->fetch_table_data( 239 array( 240 'search_string' => $search_string, 241 'offset' => $offset, 242 'per_page' => $per_page, 243 'wpdb_table' => $wpdb_table, 244 'orderby' => $orderby, 245 'order' => $order, 246 'plugin' => $plugin, 247 ) 248 ); 210 249 211 250 $columns = self::manage_columns( array() ); … … 282 321 * Fetch table data from the WordPress database. 283 322 * 323 * @param array $args - The arguments collected / passed. 324 * 284 325 * @since 1.0.0 326 * @since latest - added $args param. 285 327 * 286 328 * @return Array 287 329 */ 288 public function fetch_table_data( ) {330 public function fetch_table_data( array $args = array() ) { 289 331 290 332 global $wpdb; 291 333 292 $per_page = self::get_screen_option_per_page(); 293 294 $current_page = $this->get_pagenum(); 295 if ( 1 < $current_page ) { 296 $offset = $per_page * ( $current_page - 1 ); 297 } else { 298 $offset = 0; 299 } 300 301 $search_string = self::escaped_search_input(); 302 303 if ( isset( $_REQUEST['plugin'] ) && ! empty( $_REQUEST['plugin'] ) ) { 304 if ( -1 === (int) $_REQUEST['plugin'] ) { 305 $plugin = -1; 306 } else { 307 $plugin = \sanitize_text_field( \wp_unslash( $_REQUEST['plugin'] ) ); 308 } 309 } else { 310 $plugin = ''; 311 } 334 // Parse. 335 $parsed_args = \wp_parse_args( 336 $args, 337 array( 338 'offset' => 0, 339 'search_string' => self::escaped_search_input(), 340 'per_page' => self::get_screen_option_per_page(), 341 'wpdb_table' => $this->get_table_name(), 342 'search_sql' => '', 343 'orderby' => self::$table::get_real_id_name(), 344 'order' => 'DESC', 345 'count' => false, 346 'plugin' => '', 347 ) 348 ); 349 350 $search_string = $parsed_args['search_string']; 351 $offset = $parsed_args['offset']; 352 $per_page = $parsed_args['per_page']; 353 $wpdb_table = $parsed_args['wpdb_table']; 354 $orderby = $parsed_args['orderby']; 355 $order = $parsed_args['order']; 356 $plugin = $parsed_args['plugin']; 312 357 313 358 $search_sql = ''; … … 315 360 if ( '' !== $search_string ) { 316 361 $search_sql = 'AND (id LIKE "%' . $wpdb->esc_like( $search_string ) . '%"'; 317 foreach ( array_keys( Requests_Log_Entity::get_ column_names_admin() ) as $value ) {362 foreach ( array_keys( Requests_Log_Entity::get_all_columns() ) as $value ) { 318 363 $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" '; 319 364 } … … 321 366 } 322 367 323 if ( '' !== $plugin && -1 !== (int) $plugin ) {368 if ( '' !== $plugin && -1 !== (int) $plugin && 0 !== (int) $plugin ) { 324 369 $search_sql .= ' AND plugin = "' . (string) $plugin . '" '; 325 370 } … … 327 372 $wpdb_table = $this->get_table_name(); 328 373 329 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : 'id'; 330 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'DESC'; 331 $query = 'SELECT 374 $query = 'SELECT 332 375 ' . implode( ', ', \array_keys( Requests_Log_Entity::get_fields() ) ) . ' 333 376 FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order; … … 757 800 </script> 758 801 <?php 759 802 if ( 'top' === $which && $this->count > 0 ) { 803 ?> 804 <div id="export-form"> 805 <div> 806 <button id="start-export" class="button" data-type-export="requests" data-search="<?php echo \esc_attr( self::escaped_search_input() ); ?>" data-plugin="<?php echo \esc_attr( $plugin ); ?>"> 807 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 808 </button> 809 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 810 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 811 </button> 812 </div> 813 814 <div id="progress-container" class="progress-wrap" style="display:none;"> 815 <div id="progress-bar"></div> 816 </div> 817 818 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 819 </div> 820 821 <?php 822 } 760 823 if ( 'top' === $which ) { 761 824 ?> 762 825 <style> 763 .flex { 764 display:flex; 765 } 766 .flex-row { 767 flex-direction:row; 768 } 769 .grow-0 { 770 flex-grow:0; 771 } 772 .p-2 { 773 padding:8px; 774 } 775 .w-full { 776 width:auto; 777 } 778 .border-t { 779 border-bottom-width:1px; 780 } 781 .justify-between { 782 justify-content:space-between; 783 } 784 .italic { 785 font-style: italic; 786 } 787 .text-lg { 788 font-size: 1.1em; 789 font-weight: bold; 790 } 791 #wpwrap { 792 overflow-x: hidden !important; 793 } 794 .wp-list-table { 795 white-space: nowrap; 796 display: block; 797 overflow-x: auto; 798 } 826 <?php echo Miscellaneous::get_flex_style(); ?> 799 827 /* .wp-list-table { 800 828 display: block; -
0-day-analytics/trunk/classes/vendor/lists/class-table-list.php
r3377720 r3380967 18 18 use ADVAN\Helpers\WP_Helper; 19 19 use ADVAN\Helpers\File_Helper; 20 use ADVAN\ Entities_Global\Common_Table;20 use ADVAN\Helpers\Miscellaneous; 21 21 use ADVAN\Lists\Views\Table_View; 22 22 use ADVAN\Lists\Traits\List_Trait; 23 use ADVAN\Entities_Global\Common_Table; 23 24 24 25 if ( ! class_exists( 'WP_List_Table' ) ) { … … 164 165 $this->handle_table_actions(); 165 166 166 $items = $this->fetch_table_data(); 167 global $wpdb; 168 169 $per_page = self::get_screen_option_per_page(); 170 171 $current_page = $this->get_pagenum(); 172 if ( 1 < $current_page ) { 173 $offset = $per_page * ( $current_page - 1 ); 174 } else { 175 $offset = 0; 176 } 177 178 $search_string = self::escaped_search_input(); 179 180 $wpdb_table = $this->get_table_name(); 181 182 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : self::$table::get_real_id_name(); 183 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'ASC'; 184 185 $items = $this->fetch_table_data( 186 array( 187 'search_string' => self::escaped_search_input(), 188 'offset' => $offset, 189 'per_page' => $per_page, 190 'wpdb_table' => $wpdb_table, 191 'orderby' => $orderby, 192 'order' => $order, 193 ) 194 ); 167 195 168 196 $columns = self::$table::manage_columns( array() ); … … 209 237 * @return array 210 238 */ 211 p rotectedfunction get_sortable_columns() {239 public function get_sortable_columns() { 212 240 $first6_columns = array_keys( self::$table::get_column_names_admin() ); 213 241 … … 239 267 * Fetch table data from the WordPress database. 240 268 * 269 * @param array $args - The arguments collected / passed. 270 * 241 271 * @since 1.0.0 272 * @since latest - added $args param. 242 273 * 243 274 * @return Array 244 275 */ 245 public function fetch_table_data( ) {276 public function fetch_table_data( array $args = array() ) { 246 277 247 278 global $wpdb; 248 279 249 $per_page = self::get_screen_option_per_page(); 250 251 $current_page = $this->get_pagenum(); 252 if ( 1 < $current_page ) { 253 $offset = $per_page * ( $current_page - 1 ); 254 } else { 255 $offset = 0; 256 } 257 258 $search_string = self::escaped_search_input(); 280 // Parse. 281 $parsed_args = \wp_parse_args( 282 $args, 283 array( 284 'offset' => 0, 285 'search_string' => self::escaped_search_input(), 286 'per_page' => self::get_screen_option_per_page(), 287 'wpdb_table' => $this->get_table_name(), 288 'orderby' => self::$table::get_real_id_name(), 289 'order' => 'DESC', 290 'count' => false, 291 ) 292 ); 293 294 $search_string = $parsed_args['search_string']; 295 $offset = $parsed_args['offset']; 296 $per_page = $parsed_args['per_page']; 297 $wpdb_table = $parsed_args['wpdb_table']; 298 $orderby = $parsed_args['orderby']; 299 $order = $parsed_args['order']; 259 300 260 301 $search_sql = ''; … … 268 309 } 269 310 270 $wpdb_table = $this->get_table_name(); 271 272 $orderby = ( isset( $_GET['orderby'] ) && '' !== trim( $_GET['orderby'] ) ) ? \esc_sql( \wp_unslash( $_GET['orderby'] ) ) : self::$table::get_real_id_name(); 273 $order = ( isset( $_GET['order'] ) && '' !== trim( $_GET['order'] ) ) ? \esc_sql( \wp_unslash( $_GET['order'] ) ) : 'ASC'; 274 $query = 'SELECT 311 $query = 'SELECT 275 312 ' . implode( ', ', self::$table::get_column_names() ) . ' 276 313 FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order; … … 279 316 280 317 // query output_type will be an associative array with ARRAY_A. 281 $query_results = $wpdb->get_results( $query, ARRAY_A ); 282 283 $this->count = (int) $wpdb->get_var( 'SELECT COUNT(' . self::$table::get_real_id_name() . ') FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql ); 318 $query_results = $wpdb->get_results( $query, ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 319 320 $this->count = (int) $wpdb->get_var( 'SELECT COUNT(' . self::$table::get_real_id_name() . ') FROM ' . $wpdb_table . ' WHERE 1=1 ' . $search_sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 284 321 285 322 // return result array to prepare_items. … … 585 622 586 623 </div> 587 588 624 <?php 625 if ( 'top' === $which && $this->count > 0 ) { 626 ?> 627 <div id="export-form"> 628 <div> 629 <button id="start-export" class="button" data-type-export="table" data-table-name="<?php echo \esc_attr( self::$table::get_name() ); ?>" data-search="<?php echo \esc_attr( self::escaped_search_input() ); ?>"> 630 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 631 </button> 632 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 633 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 634 </button> 635 </div> 636 637 <div id="progress-container" class="progress-wrap" style="display:none;"> 638 <div id="progress-bar"></div> 639 </div> 640 641 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 642 </div> 643 644 <?php 645 } 589 646 // if ( 'top' === $which ) { 590 647 global $wpdb; 591 648 ?> 592 <script> 593 jQuery('form .table_filter').on('change', function(e) { 594 jQuery('form .table_filter').val(jQuery(this).val()); 595 jQuery( this ).closest( 'form' ).attr( 'action', '<?php echo \esc_url( \admin_url( 'admin-post.php' ) ); ?>').append('<input type="hidden" name="action" value="<?php echo \esc_attr( self::SWITCH_ACTION ); ?>">').append('<?php \wp_nonce_field( self::SWITCH_ACTION, self::SWITCH_ACTION . 'nonce' ); ?>').submit(); 596 }); 597 </script> 649 <script> 650 jQuery('form .table_filter').on('change', function(e) { 651 jQuery('form .table_filter').val(jQuery(this).val()); 652 jQuery( this ).closest( 'form' ).attr( 'action', '<?php echo \esc_url( \admin_url( 'admin-post.php' ) ); ?>').append('<input type="hidden" name="action" value="<?php echo \esc_attr( self::SWITCH_ACTION ); ?>">').append('<?php \wp_nonce_field( self::SWITCH_ACTION, self::SWITCH_ACTION . 'nonce' ); ?>').submit(); 653 }); 654 655 function makeSearchableDropdown(selectEl) { 656 selectEl.style.display = "none"; 657 658 const container = document.createElement("div"); 659 container.className = "dropdown-container"; 660 661 const input = document.createElement("input"); 662 input.className = "dropdown-search"; 663 input.placeholder = "<?php \esc_html_e( 'Search tables...', '0-day-analytics' ); ?>"; 664 input.type = "search"; 665 input.style.fontFamily = "dashicons"; 666 667 const clearBtn = document.createElement("button"); 668 clearBtn.className = "clear-btn"; 669 clearBtn.type = "button"; 670 //clearBtn.textContent = "✕"; 671 672 const list = document.createElement("div"); 673 list.className = "dropdown-list"; 674 675 container.appendChild(input); 676 container.appendChild(clearBtn); 677 container.appendChild(list); 678 selectEl.parentNode.insertBefore(container, selectEl.nextSibling); 679 680 const options = Array.from(selectEl.options); 681 let filteredOptions = options; 682 let activeIndex = -1; 683 684 // --- Measure dropdown width based on longest option --- 685 const measurer = document.createElement("span"); 686 measurer.className = "text-measurer"; 687 document.body.appendChild(measurer); 688 measurer.style.font = getComputedStyle(input).font; 689 690 let maxWidth = 0; 691 options.forEach(opt => { 692 measurer.textContent = opt.text; 693 maxWidth = Math.max(maxWidth, measurer.offsetWidth); 694 }); 695 measurer.remove(); 696 697 const inputWidth = input.offsetWidth; 698 const dropdownWidth = Math.max(maxWidth + 30, inputWidth); 699 list.style.width = dropdownWidth + "px"; 700 701 // --- Fill input with current selected value --- 702 const selectedOption = selectEl.options[selectEl.selectedIndex]; 703 if (selectedOption && selectedOption.text) { 704 input.value = selectedOption.text; 705 clearBtn.style.display = "block"; 706 } 707 708 // --- Clear button logic --- 709 clearBtn.addEventListener("click", () => { 710 input.value = ""; 711 // selectEl.value = ""; 712 clearBtn.style.display = "none"; 713 // const event = new Event("change", { bubbles: true }); 714 // selectEl.dispatchEvent(event); 715 renderList(""); 716 input.focus(); 717 }); 718 719 // --- Rendering dropdown list --- 720 function renderList(filter = "") { 721 list.innerHTML = ""; 722 filteredOptions = options.filter(opt => 723 opt.text.toLowerCase().includes(filter.toLowerCase()) 724 ); 725 726 filteredOptions.forEach((opt, i) => { 727 const item = document.createElement("div"); 728 item.textContent = opt.text; 729 item.className = "dropdown-item"; 730 if (i === activeIndex) item.classList.add("active"); 731 item.addEventListener("mousedown", e => { 732 e.preventDefault(); 733 selectOption(opt); 734 }); 735 list.appendChild(item); 736 }); 737 738 list.style.display = filteredOptions.length ? "block" : "none"; 739 if (activeIndex >= 0) scrollActiveIntoView(); 740 } 741 742 // --- Handle selection --- 743 function selectOption(opt) { 744 input.value = opt.text; 745 selectEl.value = opt.value; 746 list.style.display = "none"; 747 clearBtn.style.display = opt.value ? "block" : "none"; 748 input.focus(); 749 const event = new Event("change", { bubbles: true }); 750 selectEl.dispatchEvent(event); 751 } 752 753 function moveActive(delta) { 754 if (!filteredOptions.length) return; 755 activeIndex = (activeIndex + delta + filteredOptions.length) % filteredOptions.length; 756 renderList(input.value); 757 } 758 759 function scrollActiveIntoView() { 760 const activeItem = list.querySelector(".active"); 761 if (activeItem) { 762 const listRect = list.getBoundingClientRect(); 763 const itemRect = activeItem.getBoundingClientRect(); 764 if (itemRect.bottom > listRect.bottom) { 765 list.scrollTop += itemRect.bottom - listRect.bottom; 766 } else if (itemRect.top < listRect.top) { 767 list.scrollTop -= listRect.top - itemRect.top; 768 } 769 } 770 } 771 772 // --- Input events --- 773 input.addEventListener("input", e => { 774 activeIndex = -1; 775 renderList(e.target.value); 776 clearBtn.style.display = e.target.value ? "block" : "none"; 777 }); 778 779 input.addEventListener("focus", () => { 780 activeIndex = -1; 781 renderList(input.value); 782 }); 783 784 input.addEventListener("keydown", e => { 785 if (list.style.display === "none" && !["ArrowDown", "ArrowUp"].includes(e.key)) return; 786 switch (e.key) { 787 case "ArrowDown": 788 e.preventDefault(); 789 moveActive(1); 790 break; 791 case "ArrowUp": 792 e.preventDefault(); 793 moveActive(-1); 794 break; 795 case "Enter": 796 e.preventDefault(); 797 if (activeIndex >= 0 && filteredOptions[activeIndex]) { 798 selectOption(filteredOptions[activeIndex]); 799 } 800 break; 801 case "Escape": 802 list.style.display = "none"; 803 break; 804 } 805 }); 806 807 document.addEventListener("click", e => { 808 if (!container.contains(e.target)) list.style.display = "none"; 809 }); 810 } 811 812 // --- Initialize --- 813 makeSearchableDropdown(document.getElementById("table_filter_<?php echo \esc_attr( $which ); ?>")); 814 815 </script> 598 816 <?php 599 817 if ( 'top' === $which ) { 600 818 ?> 601 819 <style> 602 .flex { 603 display:flex; 604 } 605 .flex-row { 606 flex-direction:row; 607 } 608 .grow-0 { 609 flex-grow:0; 610 } 611 .p-2 { 612 padding:8px; 613 } 614 .w-full { 615 width:auto; 616 } 617 .border-t { 618 border-bottom-width:1px; 619 } 620 .justify-between { 621 justify-content:space-between; 622 } 623 .italic { 624 font-style: italic; 625 } 626 .text-lg { 627 font-size: 1.1em; 628 font-weight: bold; 629 } 630 #wpwrap { 631 overflow-x: hidden !important; 632 } 633 .wp-list-table { 634 white-space: nowrap; 635 display: block; 636 overflow-x: auto; 637 } 820 <?php echo Miscellaneous::get_flex_style(); ?> 638 821 /* .wp-list-table { 639 822 display: block; … … 650 833 top: 0; 651 834 } */ 652 653 </style> 835 .dropdown-container { 836 position: relative; 837 display: inline-block; 838 font-family: dashicons; 839 } 840 841 .dropdown-search { 842 width: 200px; /* fixed input width */ 843 box-sizing: border-box; 844 padding: 6px 28px 6px 6px; /* space for clear button */ 845 font-size: 14px; 846 } 847 848 /* 🔘 Clear button styling */ 849 .clear-btn { 850 position: absolute; 851 right: 6px; 852 top: 50%; 853 transform: translateY(-50%); 854 width: 18px; 855 height: 18px; 856 border: 1px solid #ccc; 857 border-radius: 50%; 858 background: white; 859 color: #666; 860 font-size: 12px; 861 font-weight: bold; 862 line-height: 1; 863 text-align: center; 864 cursor: pointer; 865 display: none; 866 padding: 0; 867 box-shadow: 0 1px 2px rgba(0,0,0,0.1); 868 } 869 870 .clear-btn:hover { 871 background: #f2f2f2; 872 color: #000; 873 border-color: #999; 874 } 875 876 .clear-btn::before { 877 content: "✕"; 878 top: -3px; 879 position: relative; 880 font-size: 0.7em; 881 color: #9e9898; 882 } 883 884 .dropdown-list { 885 position: absolute; 886 top: 100%; 887 left: 0; 888 border: 1px solid #ccc; 889 border-top: none; 890 max-height: 150px; 891 overflow-y: auto; 892 background: #fff; 893 display: none; 894 z-index: 100; 895 min-width: 100%; 896 } 897 898 .dropdown-item { 899 padding: 6px; 900 cursor: pointer; 901 white-space: nowrap; 902 } 903 904 .dropdown-item:hover, 905 .dropdown-item.active { 906 background-color: #0078d4; 907 color: #fff; 908 } 909 910 .text-measurer { 911 position: absolute; 912 visibility: hidden; 913 white-space: nowrap; 914 font-size: 14px; 915 font-family: sans-serif; 916 left: -9999px; 917 top: -9999px; 918 } 919 </style> 654 920 <?php } ?> 655 921 <div class="flex flex-row grow-0 p-2 w-full border-0 border-t border-solid justify-between"> -
0-day-analytics/trunk/classes/vendor/lists/class-transients-list.php
r3375318 r3380967 19 19 use ADVAN\Helpers\WP_Helper; 20 20 use ADVAN\Helpers\Crons_Helper; 21 use ADVAN\Helpers\Miscellaneous; 21 22 use ADVAN\Lists\Traits\List_Trait; 22 23 use ADVAN\Helpers\Transients_Helper; … … 276 277 $this->fetch_table_data( 277 278 array( 278 'search' => $search,279 'offset' => $offset,280 ' number'=> $per_page,281 'orderby' => $orderby,282 'order' => $order,283 'type' => $type,279 'search' => $search, 280 'offset' => $offset, 281 'per_page' => $per_page, 282 'orderby' => $orderby, 283 'order' => $order, 284 'type' => $type, 284 285 ) 285 286 ); … … 327 328 * @return array 328 329 */ 329 p rotectedfunction get_sortable_columns() {330 public function get_sortable_columns() { 330 331 // Currently there is no way to implement sorting because of the way they are stored in the database. 331 332 return array( … … 377 378 $args, 378 379 array( 379 'offset' => 0,380 ' number' => self::get_screen_option_per_page(),381 'search' => '',382 'count' => false,380 'offset' => 0, 381 'per_page' => self::get_screen_option_per_page(), 382 'search' => '', 383 'count' => false, 383 384 ) 384 385 ); … … 451 452 452 453 $actions['delete'] = '<a class="aadvana-transient-delete" href="#" data-nonce="' . $query_args_view_data['_wpnonce'] . '" data-id="' . $query_args_view_data['hash'] . '">' . \esc_html__( 'Delete', '0-day-analytics' ) . '</a>'; 454 455 $actions['view'] = '<a class="aadvana-tablerow-view" href="#" data-details-id="' . $query_args_view_data['hash'] . '">' . \esc_html__( 'View', '0-day-analytics' ) . '</a>'; 453 456 454 457 $edit_url = \remove_query_arg( … … 591 594 592 595 ?> 593 <script>594 window.location.href = '<?php echo $redirect; ?>';595 </script>596 <script> 597 window.location.href = '<?php echo \esc_url_raw( $redirect ); ?>'; 598 </script> 596 599 <?php 597 600 } … … 689 692 </script> 690 693 <style> 694 <?php echo Miscellaneous::get_flex_style(); ?> 691 695 .generated-transients .persistent th:nth-child(1) { 692 696 border-left: 7px solid #d2ab0e !important; … … 711 715 } 712 716 $this->extra_tablenav( $which ); 717 if ( 'top' === $which && $this->count > 0 ) { 718 ?> 719 <div id="export-form"> 720 <div> 721 <button id="start-export" class="button" data-type-export="transients" data-transient-type="<?php echo isset( $_GET['event_type'] ) ? \esc_attr( \sanitize_text_field( \wp_unslash( $_GET['event_type'] ) ) ) : 'all'; ?>" data-search="<?php echo self::escaped_search_input(); ?>"> 722 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 723 </button> 724 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 725 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 726 </button> 727 </div> 728 729 <div id="progress-container" class="progress-wrap" style="display:none;"> 730 <div id="progress-bar"></div> 731 </div> 732 733 <p id="progress-text" style="display:none;"><?php echo esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 734 </div> 735 736 <?php 737 } 738 713 739 $this->pagination( $which ); 714 740 … … 772 798 * @since 1.4.0 773 799 */ 774 p rotectedfunction get_table_classes() {800 public function get_table_classes() { 775 801 return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] ); 776 802 } -
0-day-analytics/trunk/classes/vendor/lists/class-wp-mail-list.php
r3378902 r3380967 21 21 use ADVAN\Controllers\WP_Mail_Log; 22 22 use ADVAN\Entities\WP_Mail_Entity; 23 use ADVAN\Helpers\Miscellaneous; 23 24 use ADVAN\Lists\Traits\List_Trait; 24 25 use ADVAN\Lists\Views\WP_Mail_View; … … 249 250 $items = $this->fetch_table_data( 250 251 array( 251 'search' => $search,252 'offset' => $offset,253 ' number'=> $per_page,254 'orderby' => $orderby,255 'order' => $order,256 'type' => $type,257 'site_id' => $site_id,252 'search' => $search, 253 'offset' => $offset, 254 'per_page' => $per_page, 255 'orderby' => $orderby, 256 'order' => $order, 257 'type' => $type, 258 'site_id' => $site_id, 258 259 ) 259 260 ); … … 346 347 $args, 347 348 array( 348 'offset' => 0,349 ' number'=> self::get_screen_option_per_page(),350 'search' => '',351 'orderby' => 'id',352 'order' => 'DESC',353 'count' => false,354 'site_id' => 0,349 'offset' => 0, 350 'per_page' => self::get_screen_option_per_page(), 351 'search' => '', 352 'orderby' => 'id', 353 'order' => 'DESC', 354 'count' => false, 355 'site_id' => 0, 355 356 ) 356 357 ); … … 368 369 if ( ! isset( $parsed_args['all'] ) ) { 369 370 370 $per_page = $parsed_args[' number'];371 $per_page = $parsed_args['per_page']; 371 372 $offset = $parsed_args['offset']; 372 373 … … 383 384 if ( '' !== $search_string ) { 384 385 $search_sql = 'AND (id LIKE "%' . $wpdb->esc_like( $search_string ) . '%"'; 385 foreach ( array_keys( WP_Mail_Entity::get_ column_names_admin() ) as $value ) {386 foreach ( array_keys( WP_Mail_Entity::get_all_columns() ) as $value ) { 386 387 $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" '; 387 388 } … … 1093 1094 <?php 1094 1095 } 1096 if ( 'top' === $which && count( $this->items )> 0) { 1097 ?> 1098 <div id="export-form"> 1099 <div> 1100 <button id="start-export" class="button" data-type-export="mail" data-search="<?php echo self::escaped_search_input(); ?>"> 1101 <?php echo \esc_html__( 'CSV Export', '0-day-analytics' ); ?> 1102 </button> 1103 <button id="cancel-export" class="button cancel-btn" style="display:none;"> 1104 <?php echo \esc_html__( 'Cancel', '0-day-analytics' ); ?> 1105 </button> 1106 </div> 1107 1108 <div id="progress-container" class="progress-wrap" style="display:none;"> 1109 <div id="progress-bar"></div> 1110 </div> 1111 1112 <p id="progress-text" style="display:none;"><?php echo \esc_html__( 'Waiting to start...', '0-day-analytics' ); ?></p> 1113 </div> 1114 1115 <?php 1116 } 1095 1117 if ( 'top' === $which ) { 1096 1118 ?> 1097 1119 <style> 1098 .flex { 1099 display:flex; 1100 } 1101 .flex-row { 1102 flex-direction:row; 1103 } 1104 .grow-0 { 1105 flex-grow:0; 1106 } 1107 .p-2 { 1108 padding:8px; 1109 } 1110 .w-full { 1111 width:auto; 1112 } 1113 .border-t { 1114 border-bottom-width:1px; 1115 } 1116 .justify-between { 1117 justify-content:space-between; 1118 } 1119 .italic { 1120 font-style: italic; 1121 } 1122 .text-lg { 1123 font-size: 1.1em; 1124 font-weight: bold; 1125 } 1126 #wpwrap { 1127 overflow-x: hidden !important; 1128 } 1129 .wp-list-table { 1130 white-space: nowrap; 1131 display: block; 1132 overflow-x: auto; 1133 } 1120 <?php echo Miscellaneous::get_flex_style(); ?> 1134 1121 /* .wp-list-table { 1135 1122 display: block; -
0-day-analytics/trunk/classes/vendor/lists/entity/class-common-table.php
r3378902 r3380967 996 996 $wpdb->suppress_errors( true ); 997 997 998 $results = $wpdb->get_results( $query, \ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 998 $results = $wpdb->get_results( $query, \ARRAY_A ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching 999 999 1000 1000 if ( '' !== $wpdb->last_error || null === $results ) { … … 1066 1066 * @since latest 1067 1067 */ 1068 p rivatestatic function format_value_for_html( $value ) {1068 public static function format_value_for_html( $value ) { 1069 1069 // Try to decode JSON if it's a string. 1070 1070 if ( is_string( $value ) ) { … … 1096 1096 $formatted = '<em>null</em>'; 1097 1097 } elseif ( is_numeric( $value ) ) { 1098 $formatted = esc_html( (string) $value );1098 $formatted = \esc_html( (string) $value ); 1099 1099 } else { 1100 1100 // Fallback to escaped plain string. 1101 $formatted = esc_html( (string) $value );1101 $formatted = \esc_html( (string) $value ); 1102 1102 } 1103 1103 -
0-day-analytics/trunk/classes/vendor/lists/traits/class-list-trait.php
r3374674 r3380967 193 193 } 194 194 } 195 196 /** 197 * Returns the value of all of the records 198 * 199 * @return int 200 * 201 * @since latest 202 */ 203 public function get_count() { 204 return $this->count; 205 } 195 206 } 196 207 } -
0-day-analytics/trunk/classes/vendor/lists/views/class-requests-view.php
r3375967 r3380967 67 67 ? absint( $_REQUEST['trans_id'] ) 68 68 : 0; 69 $transient = Transients_Helper::get_transient_by_id( $transient_id );69 $transient = Transients_Helper::get_transient_by_id( null, $transient_id ); 70 70 $name = Transients_Helper::get_transient_name( $transient['option_name'] ); 71 71 $expiration = Transients_Helper::get_transient_expiration_time( $transient['option_name'] ); -
0-day-analytics/trunk/classes/vendor/lists/views/class-table-view.php
r3377720 r3380967 208 208 <p> 209 209 <b><?php \esc_html_e( 'Table', '0-day-analytics' ); ?>:</b> 210 <span class="table-name"><?php echo \esc_html( $table_name); ?></span><br>210 <span class="table-name"><?php echo \esc_html( $table_name ); ?></span><br> 211 211 </p> 212 212 <div class="aadvana-panel-wrapper"> … … 217 217 <h3><?php \esc_html_e( 'Row data:', '0-day-analytics' ); ?></h3> 218 218 </div> 219 <div class=""><span title="<?php echo __( 'Copy to clipboard (as raw HTML)', '0-day-analytics' ); ?>" class="dashicons dashicons-clipboard" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span> <span title="<?php esc_html_e( 'Share', '0-day-analytics' ); ?>" class="dashicons dashicons-share" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span></div>219 <div class=""><span title="<?php \esc_html_e( 'Copy to clipboard (as raw HTML)', '0-day-analytics' ); ?>" class="dashicons dashicons-clipboard" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span> <span title="<?php esc_html_e( 'Share', '0-day-analytics' ); ?>" class="dashicons dashicons-share" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span></div> 220 220 </div> 221 221 <div class="http-request-args aadvana-pre-300" style="background: #fff;color:#000;"> … … 244 244 try { 245 245 attResp = wp.apiFetch({ 246 path: '/<?php echo Endpoints::ENDPOINT_ROOT_NAME; ?>/v1/get_table_record/<?php echo $table_name?>/' + id + '/',246 path: '/<?php echo \esc_attr( Endpoints::ENDPOINT_ROOT_NAME ); ?>/v1/get_table_record/<?php echo \esc_attr( $table_name ); ?>/' + id + '/', 247 247 method: 'GET', 248 248 cache: 'no-cache' … … 273 273 274 274 jQuery(document).on('click', '.media-modal-close', function () { 275 jQuery('.media-modal .http-request-args').html('<?php \esc_html_e( 'Loading please wait...', '0-day-analytics' ); ?>');275 jQuery('.media-modal .http-request-args').html('<?php \esc_html_e( 'Loading please wait...', '0-day-analytics' ); ?>'); 276 276 //jQuery('.media-modal .table-name').html(''); 277 277 jQuery('.media-modal').removeClass('open'); … … 283 283 if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) { 284 284 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 285 286 console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())287 285 288 286 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); -
0-day-analytics/trunk/classes/vendor/lists/views/class-transients-view.php
r3374674 r3380967 16 16 use ADVAN\Helpers\WP_Helper; 17 17 use ADVAN\Lists\Transients_List; 18 use ADVAN\ControllersApi\Endpoints; 18 19 use ADVAN\Helpers\Transients_Helper; 19 20 … … 40 41 public static function analytics_transients_page() { 41 42 \wp_enqueue_script( 'wp-api-fetch' ); 43 \wp_enqueue_style( 'media-views' ); 44 \wp_enqueue_script( 'wp-api-fetch' ); 42 45 ?> 43 46 <script> … … 62 65 ? absint( $_REQUEST['trans_id'] ) 63 66 : 0; 64 $transient = Transients_Helper::get_transient_by_id( $transient_id );67 $transient = Transients_Helper::get_transient_by_id( null, $transient_id ); 65 68 66 69 if ( null !== $transient ) { … … 72 75 73 76 $next_run_gmt = gmdate( 'Y-m-d H:i:s', $expiration ); 74 $next_run_date_local = get_date_from_gmt( $next_run_gmt, 'Y-m-d' );75 $next_run_time_local = get_date_from_gmt( $next_run_gmt, 'H:i:s' );77 $next_run_date_local = \get_date_from_gmt( $next_run_gmt, 'Y-m-d' ); 78 $next_run_time_local = \get_date_from_gmt( $next_run_gmt, 'H:i:s' ); 76 79 } 77 80 } … … 285 288 </form> 286 289 </div> 290 291 <style> 292 /* modal */ 293 .media-modal, 294 .media-modal-backdrop { 295 display: none; 296 } 297 298 .media-modal.open, 299 .media-modal-backdrop.open { 300 display: block; 301 } 302 303 #aadvana-modal.aadvana-modal .media-frame-title, 304 #aadvana-modal.aadvana-modal .media-frame-content { 305 left: 0; 306 } 307 308 .media-frame-router { 309 left: 10px; 310 } 311 #aadvana-modal.aadvana-modal 312 .media-frame-content { 313 top: 48px; 314 bottom: 0; 315 overflow: auto; 316 } 317 318 .button-link.media-modal-close { 319 cursor: pointer; 320 text-decoration: none; 321 } 322 323 .aadvana-modal-buttons{ 324 position: absolute; 325 top: 0; 326 right: 0; 327 } 328 .aadvana-modal-buttons .media-modal-close{ 329 position: relative; 330 width: auto; 331 padding: 0 .5rem; 332 } 333 334 .media-modal-close.prev .media-modal-icon::before { 335 content: "\f342"; 336 } 337 338 .media-modal-close.next .media-modal-icon::before { 339 content: "\f346"; 340 } 341 342 .modal-content-wrap { 343 padding: 16px; 344 } 345 346 /* tab and panel */ 347 .aadvana-modal .nav-tab-active{ 348 border-bottom: solid 1px white; 349 background-color: white; 350 } 351 .aadvana-panel-active{ 352 display:block; 353 margin: 1rem 0; 354 } 355 356 .wrapper { 357 text-align: center; 358 } 359 .wrapper .box{ 360 text-align: left; 361 background-color: #f4f5f6; 362 padding: .5rem; 363 border-radius: .5rem; 364 margin-bottom: 1rem; 365 display: inline-block; 366 vertical-align: top; 367 box-sizing: border-box; 368 } 369 html.aadvana-darkskin .wrapper .box { 370 background-color: #1d456b !important; 371 border: 1px solid #ccc; 372 } 373 html.aadvana-darkskin .media-frame-content { 374 background-color: #1d456b !important; 375 } 376 .wrapper #mail-body { 377 width: 99%; 378 } 379 @media screen and (max-width: 782px) { 380 381 .wrapper .box{ 382 display: block; 383 width: auto; 384 } 385 } 386 387 </style> 388 389 <div id="aadvana-modal" class="media-modal aadvana-modal"> 390 <div class="aadvana-modal-buttons"> 391 <button class="button-link media-modal-close"><span class="media-modal-icon"></span></button> 392 </div> 393 <div class="media-modal-content"> 394 <div class="media-frame"> 395 <div class="media-frame-title"> 396 <h1><?php \esc_html_e( 'Transient details:', '0-day-analytics' ); ?></h1> 397 </div> 398 <div class="media-frame-content"> 399 <div class="modal-content-wrap"> 400 <p> 401 <b><?php \esc_html_e( 'Transient', '0-day-analytics' ); ?>:</b> 402 <span class="transient-name"></span><br> 403 </p> 404 <div class="aadvana-panel-wrapper"> 405 <div class="aadvana-request-response aadvana-panel-active wrapper"> 406 <div class="box" id="mail-body"> 407 <div class="flex flex-row grow-0 p-2 w-full border-0 border-t border-solid justify-between"> 408 <div> 409 <h3><?php \esc_html_e( 'Transient data:', '0-day-analytics' ); ?></h3> 410 </div> 411 <div class=""><span title="<?php \esc_html_e( 'Copy to clipboard (as raw HTML)', '0-day-analytics' ); ?>" class="dashicons dashicons-clipboard" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span> <span title="<?php esc_html_e( 'Share', '0-day-analytics' ); ?>" class="dashicons dashicons-share" style="cursor:pointer;font-family: dashicons !important;" aria-hidden="true"></span></div> 412 </div> 413 <div class="http-request-args aadvana-pre-300" style="background: #fff;color:#000;"> 414 <?php 415 \esc_html_e( 'Loading please wait...', '0-day-analytics' ); 416 ?> 417 418 </div> 419 </div> 420 </div> 421 </div> 422 </div> 423 </div> 424 </div> 425 </div> 426 </div> 427 <div class="media-modal-backdrop"></div> 428 429 <script> 430 431 jQuery(document).on('click', '.aadvana-tablerow-view', function( e ) { 432 e.preventDefault(); 433 let id = jQuery( this ).data( 'details-id' ); 434 let that = this; 435 var encodedValue = jQuery('<div />').text(id).html(); 436 try { 437 attResp = wp.apiFetch({ 438 path: '/<?php echo \esc_attr( Endpoints::ENDPOINT_ROOT_NAME ); ?>/v1/get_transient_record/' + id + '/', 439 method: 'GET', 440 cache: 'no-cache' 441 }).then( ( attResp ) => { 442 443 jQuery('.media-modal .http-request-args').html(attResp.mail_body); 444 jQuery('.media-modal .transient-name').html(attResp.transient_name); 445 446 } ).catch( 447 ( error ) => { 448 if (error.message) { 449 jQuery(that).closest("tr").after('<tr><td style="overflow:hidden;" colspan="'+(jQuery(that).closest("tr").find("td").length+1)+'"><div class="error" style="background:#fff; color:#000;"> ' + error.message + '</div></td></tr>'); 450 } 451 } 452 ); 453 } catch (error) { 454 throw error; 455 } finally { 456 jQuery(that).css({ 457 "pointer-events": "", 458 "cursor": "" 459 }) 460 } 461 462 jQuery('.media-modal').addClass('open'); 463 jQuery('.media-modal-backdrop').addClass('open'); 464 }); 465 466 jQuery(document).on('click', '.media-modal-close', function () { 467 jQuery('.media-modal .http-request-args').html('<?php \esc_html_e( 'Loading please wait...', '0-day-analytics' ); ?>'); 468 jQuery('.media-modal .transient-name').html(''); 469 jQuery('.media-modal').removeClass('open'); 470 jQuery('.media-modal-backdrop').removeClass('open'); 471 }); 472 473 jQuery( document ).on( 'click', '.dashicons.dashicons-clipboard', function( e ) { 474 475 if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) { 476 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 477 478 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); 479 // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection 480 // selectedText = jQuery(selectedText).text(); 481 482 navigator.clipboard.writeText(selectedText); 483 } 484 485 }); 486 487 jQuery( document ).ready( function() { 488 489 if ( navigator.share ) { 490 491 jQuery( document ).on( 'click', '.dashicons.dashicons-share', function( e ) { 492 493 if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) { 494 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 495 496 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); 497 // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection 498 // selectedText = jQuery(selectedText).text(); 499 500 const shareData = { 501 text: selectedText + '\n\n' + "<?php echo \get_site_url(); ?>", 502 }; 503 504 try { 505 navigator.share(shareData); 506 } catch (err) { 507 jQuery(this).text( `Error: ${err}` ); 508 } 509 510 } 511 }); 512 513 } else { 514 jQuery( '.dashicons.dashicons-share' ).remove(); 515 } 516 }); 517 </script> 287 518 <?php 519 288 520 } 289 521 } -
0-day-analytics/trunk/classes/vendor/lists/views/class-wp-mail-view.php
r3375967 r3380967 452 452 let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html(); 453 453 454 console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())455 456 454 // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n"); 457 455 // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection -
0-day-analytics/trunk/css/admin/style.css
r3378902 r3380967 2664 2664 html.aadvana-darkskin .wp-core-ui textarea:hover, 2665 2665 html.aadvana-darkskin .wp-core-ui textarea:focus, 2666 html.aadvana-darkskin .wp-core-ui textarea:active { 2666 html.aadvana-darkskin .wp-core-ui textarea:active, 2667 html.aadvana-darkskin .wp-core-ui .dropdown-item { 2667 2668 background-color: #062038; 2668 2669 border-color: #383a3f; -
0-day-analytics/trunk/js/admin/aadvana-settings.js
r3357219 r3380967 242 242 ------------------------------------------------------------------------------------------ */ 243 243 $searchSettings = jQuery('#aadvana-panel-search'), 244 $searchList= jQuery('#aadvana-search-list');244 $searchList0 = jQuery('#aadvana-search-list'); 245 245 246 246 $searchSettings.on('keyup', function () { 247 247 var valThis = $searchSettings.val().toLowerCase(); 248 $searchList .html('');248 $searchList0.html(''); 249 249 250 250 if (valThis == '') { … … 265 265 thistextparentid = $thisparent.attr('id'); 266 266 267 $searchList .append('<li><a href="#" data-section="' + thistextid + '" data-url="' + thistextparentid + '"><strong>' + thistextparent + '</strong> / ' + thistext + '</a></li>');267 $searchList0.append('<li><a href="#" data-section="' + thistextid + '" data-url="' + thistextparentid + '"><strong>' + thistextparent + '</strong> / ' + thistext + '</a></li>'); 268 268 } 269 269 else { … … 274 274 }); 275 275 276 $searchList .on('click', 'a', function () {276 $searchList0.on('click', 'a', function () { 277 277 var $thisElem = jQuery(this), 278 278 tabId = $thisElem.data('url'), … … 292 292 293 293 if (!container.is(e.target) && container.has(e.target).length === 0) { 294 $searchList .html('');294 $searchList0.html(''); 295 295 $searchSettings.val(''); 296 296 jQuery('.highlights-search').removeClass('highlights-search'); -
0-day-analytics/trunk/readme.txt
r3378902 r3380967 4 4 Tested up to: 6.8 5 5 Requires PHP: 7.4 6 Stable tag: 3. 7.66 Stable tag: 3.8.0 7 7 License: GPLv3 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-3.0.txt … … 96 96 The plugin auto-detects default error log location, usually WordPress defines that in `wp-config.php`. You can customize this path if needed - this is strongly recommended for security reasons, and don't worry - you can do it with one click from plugin settings. 97 97 98 = Note =99 Because of its extremely poor implementation and interfering with the proper WordPress workflow (debug log set, constant pollution of the log file, improper JS implementation etc.), *Log-IQ* plugin is automatically deactivated.100 101 98 == Screenshots == 102 99 … … 113 110 == Changelog == 114 111 112 = 3.8.0 = 113 Added CSV export functionality to the modules. Code optimizations. 114 115 115 = 3.7.6 = 116 116 Resolved bug with bulk actions thanks to @lucianwpwhite . UI improvements for mobile, implemented formatting in table view, based on the typo of the value. -
0-day-analytics/trunk/vendor/composer/autoload_classmap.php
r3375967 r3380967 31 31 'ADVAN\\Helpers\\File_Helper' => $baseDir . '/classes/vendor/helpers/class-file-helper.php', 32 32 'ADVAN\\Helpers\\Log_Line_Parser' => $baseDir . '/classes/vendor/helpers/class-log-line-parser.php', 33 'ADVAN\\Helpers\\Miscellaneous' => $baseDir . '/classes/vendor/helpers/class-miscellaneous.php', 33 34 'ADVAN\\Helpers\\PHP_Helper' => $baseDir . '/classes/vendor/helpers/class-php-helper.php', 34 35 'ADVAN\\Helpers\\Plugin_Theme_Helper' => $baseDir . '/classes/vendor/helpers/class-plugin-theme-helper.php', -
0-day-analytics/trunk/vendor/composer/autoload_static.php
r3375967 r3380967 46 46 'ADVAN\\Helpers\\File_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-file-helper.php', 47 47 'ADVAN\\Helpers\\Log_Line_Parser' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-log-line-parser.php', 48 'ADVAN\\Helpers\\Miscellaneous' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-miscellaneous.php', 48 49 'ADVAN\\Helpers\\PHP_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-php-helper.php', 49 50 'ADVAN\\Helpers\\Plugin_Theme_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-plugin-theme-helper.php',
Note: See TracChangeset
for help on using the changeset viewer.