Plugin Directory

Changeset 3380967


Ignore:
Timestamp:
10/19/2025 08:22:54 PM (5 months ago)
Author:
awesomefootnotes
Message:

Adding the first version of my plugin

Location:
0-day-analytics
Files:
6 added
46 edited
1 copied

Legend:

Unmodified
Added
Removed
  • 0-day-analytics/tags/3.8.0/advanced-analytics.php

    r3378902 r3380967  
    1111 * Plugin Name:     0 Day Analytics
    1212 * Description:     Take full control of error log, crons, transients, plugins, requests, mails and DB tables.
    13  * Version:         3.7.6
     13 * Version:         3.8.0
    1414 * Author:          Stoil Dobrev
    1515 * Author URI:      https://github.com/sdobreff/
     
    3737// Constants.
    3838if ( ! defined( 'ADVAN_VERSION' ) ) {
    39     define( 'ADVAN_VERSION', '3.7.6' );
     39    define( 'ADVAN_VERSION', '3.8.0' );
    4040    define( 'ADVAN_TEXTDOMAIN', '0-day-analytics' );
    4141    define( 'ADVAN_NAME', '0 Day Analytics' );
     
    129129\add_action( 'wp_mail_failed', array( WP_Error_Handler::class, 'on_mail_error' ), -1 );
    130130
    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' );
    133133
    134134if ( ! WP_Helper::is_multisite() && \wp_is_recovery_mode() ) {
     
    220220         * Because of its extremely poor implementation, the log-iq plugin must be deactivated as it interferes very badly with the proper WP work.
    221221         */
    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        // }
    225225    }
    226226}
  • 0-day-analytics/tags/3.8.0/classes/vendor/controllers/class-endpoints.php

    r3377720 r3380967  
    1616
    1717use ADVAN\Lists\Logs_List;
     18use ADVAN\Lists\WP_Mail_List;
    1819use ADVAN\Lists\Requests_List;
     20use ADVAN\Helpers\Crons_Helper;
     21use ADVAN\Helpers\Transients_Helper;
    1922use ADVAN\Entities_Global\Common_Table;
    20 use ADVAN\Helpers\Crons_Helper;
    21 use ADVAN\Lists\WP_Mail_List;
    2223
    2324defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
     
    242243                                        'pattern'     => '.+',
    243244                                        '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',
    244270                                    ),
    245271                                ),
  • 0-day-analytics/tags/3.8.0/classes/vendor/entities/class-abstract-entity.php

    r3375967 r3380967  
    770770            return $results;
    771771        }
     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        }
    772783    }
    773784}
  • 0-day-analytics/tags/3.8.0/classes/vendor/helpers/class-ajax-helper.php

    r3377720 r3380967  
    1212namespace ADVAN\Helpers;
    1313
     14use ADVAN\Lists\Logs_List;
    1415use ADVAN\Helpers\Settings;
     16use ADVAN\Lists\Crons_List;
     17use ADVAN\Lists\Table_List;
    1518use ADVAN\Controllers\Slack;
    1619use ADVAN\Helpers\WP_Helper;
     20use ADVAN\Lists\WP_Mail_List;
     21use ADVAN\Lists\Requests_List;
    1722use ADVAN\Controllers\Telegram;
    1823use ADVAN\Controllers\Error_Log;
     24use ADVAN\Controllers\Slack_API;
     25use ADVAN\Lists\Transients_List;
     26use ADVAN\Controllers\Telegram_API;
     27use ADVAN\Entities_Global\Common_Table;
    1928use ADVAN\Controllers\Mail_SMTP_Settings;
    20 use ADVAN\Controllers\Slack_API;
    21 use ADVAN\Controllers\Telegram_API;
    22 use ADVAN\Lists\Logs_List;
    2329
    2430// Exit if accessed directly.
     
    141147
    142148                \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' ) );
    143152            }
    144153        }
     
    650659            \wp_die();
    651660        }
     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        }
    652934    }
    653935}
  • 0-day-analytics/tags/3.8.0/classes/vendor/helpers/class-settings.php

    r3374674 r3380967  
    306306                'wp-api-fetch'
    307307            );
     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.
    308345
    309346            ?>
  • 0-day-analytics/tags/3.8.0/classes/vendor/helpers/class-transients-helper.php

    r3374674 r3380967  
    1515
    1616use ADVAN\Lists\Transients_List;
     17use ADVAN\Entities_Global\Common_Table;
    1718
    1819// Exit if accessed directly.
     
    148149         * Retrieve a transient by its ID
    149150         *
    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.
    151153         *
    152154         * @return array
    153155         *
    154156         * @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 ) {
    157160            global $wpdb;
    158161
     
    161164            // Bail if empty ID.
    162165            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                }
    164172            }
    165173
     
    168176
    169177            // 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            }
    171277        }
    172278
     
    334440                    $type = \esc_html__( 'json', '0-day-analytics' );
    335441                } 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' );
    337443
    338444                    // Scalar.
     
    392498
    393499            // Escape some LIKE parts.
    394             $esc_name = '' . $wpdb->esc_like( '_transient_' ) . '%';
     500            $esc_name      = '' . $wpdb->esc_like( '_transient_' ) . '%';
    395501            $esc_site_name = '' . $wpdb->esc_like( '_site_transient_' ) . '%';
    396             $esc_time = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%';
     502            $esc_time      = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%';
    397503
    398504            // SELECT.
     
    410516            // if ( empty( $parsed_args['count'] ) ) {
    411517
    412                 // FROM.
    413                
     518            // FROM.
     519
    414520            // old - ON d.option_name LIKE CONCAT('%_transient_timeout_', SUBSTRING_INDEX( go.option_name, '_transient_', -1 ), '%')
    415521
    416                 $sql[] = "LEFT JOIN
     522            $sql[] = "LEFT JOIN
    417523                {$wpdb->options} d
    418524                ON d.option_name = CONCAT(
     
    456562            if ( empty( $parsed_args['count'] ) && empty( $parsed_args['all'] ) ) {
    457563                $offset = absint( $parsed_args['offset'] );
    458                 $number = absint( $parsed_args['number'] );
     564                $per_page = absint( $parsed_args['per_page'] );
    459565
    460566                // if ( ! empty( $parsed_args['orderby'] ) && \in_array( $parsed_args['orderby'], array( 'transient_name' ) ) ) {
     
    475581                // );
    476582                // } 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 );
    478584                // }
    479585            }
     
    487593            // Query.
    488594            $transients = empty( $parsed_args['count'] )
    489                 ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    490                 : $wpdb->get_var( $prepared, 0 );    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
     595            ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
     596            : $wpdb->get_var( $prepared, 0 );    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    491597
    492598            if ( empty( $parsed_args['count'] ) && ! empty( $transients ) ) {
     
    496602                        'transient_name' => self::get_transient_name( $transient['option_name'] ),
    497603                        'value'          => self::get_transient_value( $transient['option_value'] ),
    498                         'schedule'       => (int) $transient['schedule'] ,
     604                        'schedule'       => (int) $transient['schedule'],
    499605                        'id'             => $transient['option_id'],
    500606                    );
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/class-crons-list.php

    r3378902 r3380967  
    352352         *
    353353         * @since 1.1.0
    354          * @since 2.9.0 - Introduced flag getting the events wihtout the type filtering
     354         * @since 2.9.0 - Introduced flag getting the events without the type filtering
    355355         */
    356356        public static function get_cron_items( bool $no_type_filtering = false ): array {
     
    926926                    </select>
    927927                    <?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>
    928944                </div>
    929945                <?php
     
    11361152            return sprintf(
    11371153                $format,
    1138                 esc_attr( $link ),
    1139                 esc_html( $text ),
     1154                \esc_attr( $link ),
     1155                \esc_html( $text ),
    11401156                ( 'edit' )
    11411157            );
     
    12021218         * @since 1.4.0
    12031219         */
    1204         protected function get_table_classes() {
     1220        public function get_table_classes() {
    12051221            return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] );
    12061222        }
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/class-logs-list.php

    r3377720 r3380967  
    11231123                            <?php
    11241124                    }
     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
    11251146                }
    11261147                ?>
     
    13451366                    </select>
    13461367                </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                            ?>
    13521374
    13531375                        <div id="advaa-filtering-notice" class="notice notice-info is-dismissible">
     
    13671389                            });
    13681390                        </script>
    1369                         <?php
    1370                     }
    1371                     ?>
     1391                            <?php
     1392                        }
     1393                        ?>
    13721394                <script>
    13731395
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/class-requests-list.php

    r3375967 r3380967  
    1818use ADVAN\Helpers\WP_Helper;
    1919use ADVAN\Helpers\File_Helper;
    20 use ADVAN\Entities_Global\Common_Table;
     20use ADVAN\Helpers\Miscellaneous;
    2121use ADVAN\Lists\Traits\List_Trait;
    2222use ADVAN\ControllersApi\Endpoints;
     
    2424use ADVAN\Helpers\Plugin_Theme_Helper;
    2525use ADVAN\Entities\Requests_Log_Entity;
     26use ADVAN\Entities_Global\Common_Table;
    2627
    2728if ( ! class_exists( 'WP_List_Table' ) ) {
     
    207208            $this->handle_table_actions();
    208209
    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            );
    210249
    211250            $columns = self::manage_columns( array() );
     
    282321         * Fetch table data from the WordPress database.
    283322         *
     323         * @param array $args - The arguments collected / passed.
     324         *
    284325         * @since 1.0.0
     326         * @since latest - added $args param.
    285327         *
    286328         * @return  Array
    287329         */
    288         public function fetch_table_data() {
     330        public function fetch_table_data( array $args = array() ) {
    289331
    290332            global $wpdb;
    291333
    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'];
    312357
    313358            $search_sql = '';
     
    315360            if ( '' !== $search_string ) {
    316361                $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 ) {
    318363                    $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" ';
    319364                }
     
    321366            }
    322367
    323             if ( '' !== $plugin && -1 !== (int) $plugin ) {
     368            if ( '' !== $plugin && -1 !== (int) $plugin && 0 !== (int) $plugin ) {
    324369                $search_sql .= ' AND plugin = "' . (string) $plugin . '" ';
    325370            }
     
    327372            $wpdb_table = $this->get_table_name();
    328373
    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
    332375                ' . implode( ', ', \array_keys( Requests_Log_Entity::get_fields() ) ) . '
    333376              FROM ' . $wpdb_table . '  WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order;
     
    757800                </script>
    758801                <?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                }
    760823                if ( 'top' === $which ) {
    761824                    ?>
    762825                <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(); ?>
    799827                    /* .wp-list-table {
    800828                        display: block;
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/class-table-list.php

    r3377720 r3380967  
    1818use ADVAN\Helpers\WP_Helper;
    1919use ADVAN\Helpers\File_Helper;
    20 use ADVAN\Entities_Global\Common_Table;
     20use ADVAN\Helpers\Miscellaneous;
    2121use ADVAN\Lists\Views\Table_View;
    2222use ADVAN\Lists\Traits\List_Trait;
     23use ADVAN\Entities_Global\Common_Table;
    2324
    2425if ( ! class_exists( 'WP_List_Table' ) ) {
     
    164165            $this->handle_table_actions();
    165166
    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            );
    167195
    168196            $columns = self::$table::manage_columns( array() );
     
    209237         * @return array
    210238         */
    211         protected function get_sortable_columns() {
     239        public function get_sortable_columns() {
    212240            $first6_columns = array_keys( self::$table::get_column_names_admin() );
    213241
     
    239267         * Fetch table data from the WordPress database.
    240268         *
     269         * @param array $args - The arguments collected / passed.
     270         *
    241271         * @since 1.0.0
     272         * @since latest - added $args param.
    242273         *
    243274         * @return  Array
    244275         */
    245         public function fetch_table_data() {
     276        public function fetch_table_data( array $args = array() ) {
    246277
    247278            global $wpdb;
    248279
    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'];
    259300
    260301            $search_sql = '';
     
    268309            }
    269310
    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
    275312                ' . implode( ', ', self::$table::get_column_names() ) . '
    276313              FROM ' . $wpdb_table . '  WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order;
     
    279316
    280317            // 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
    284321
    285322            // return result array to prepare_items.
     
    585622               
    586623            </div>
    587 
    588624            <?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            }
    589646            // if ( 'top' === $which ) {
    590647            global $wpdb;
    591648            ?>
    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>
    598816                        <?php
    599817                        if ( 'top' === $which ) {
    600818                            ?>
    601819                <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(); ?>
    638821                    /* .wp-list-table {
    639822                        display: block;
     
    650833                        top: 0;
    651834                    } */
    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>
    654920                        <?php } ?>
    655921                <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  
    1919use ADVAN\Helpers\WP_Helper;
    2020use ADVAN\Helpers\Crons_Helper;
     21use ADVAN\Helpers\Miscellaneous;
    2122use ADVAN\Lists\Traits\List_Trait;
    2223use ADVAN\Helpers\Transients_Helper;
     
    276277            $this->fetch_table_data(
    277278                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,
    284285                )
    285286            );
     
    327328         * @return array
    328329         */
    329         protected function get_sortable_columns() {
     330        public function get_sortable_columns() {
    330331            // Currently there is no way to implement sorting because of the way they are stored in the database.
    331332            return array(
     
    377378                $args,
    378379                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,
    383384                )
    384385            );
     
    451452
    452453                    $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>';
    453456
    454457                    $edit_url = \remove_query_arg(
     
    591594
    592595                ?>
    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>
    596599                <?php
    597600            }
     
    689692                </script>
    690693                <style>
     694                    <?php echo Miscellaneous::get_flex_style(); ?>
    691695                    .generated-transients .persistent th:nth-child(1) {
    692696                        border-left: 7px solid #d2ab0e !important;
     
    711715            }
    712716            $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
    713739            $this->pagination( $which );
    714740
     
    772798         * @since 1.4.0
    773799         */
    774         protected function get_table_classes() {
     800        public function get_table_classes() {
    775801            return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] );
    776802        }
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/class-wp-mail-list.php

    r3378902 r3380967  
    2121use ADVAN\Controllers\WP_Mail_Log;
    2222use ADVAN\Entities\WP_Mail_Entity;
     23use ADVAN\Helpers\Miscellaneous;
    2324use ADVAN\Lists\Traits\List_Trait;
    2425use ADVAN\Lists\Views\WP_Mail_View;
     
    249250            $items = $this->fetch_table_data(
    250251                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,
    258259                )
    259260            );
     
    346347                $args,
    347348                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,
    355356                )
    356357            );
     
    368369            if ( ! isset( $parsed_args['all'] ) ) {
    369370
    370                 $per_page = $parsed_args['number'];
     371                $per_page = $parsed_args['per_page'];
    371372                $offset   = $parsed_args['offset'];
    372373
     
    383384                if ( '' !== $search_string ) {
    384385                    $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 ) {
    386387                        $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" ';
    387388                    }
     
    10931094                <?php
    10941095            }
     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            }
    10951117            if ( 'top' === $which ) {
    10961118                ?>
    10971119                <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(); ?>
    11341121                    /* .wp-list-table {
    11351122                        display: block;
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/entity/class-common-table.php

    r3378902 r3380967  
    996996            $wpdb->suppress_errors( true );
    997997
    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
    999999
    10001000            if ( '' !== $wpdb->last_error || null === $results ) {
     
    10661066         * @since latest
    10671067         */
    1068         private static function format_value_for_html( $value ) {
     1068        public static function format_value_for_html( $value ) {
    10691069            // Try to decode JSON if it's a string.
    10701070            if ( is_string( $value ) ) {
     
    10961096                $formatted = '<em>null</em>';
    10971097            } elseif ( is_numeric( $value ) ) {
    1098                 $formatted = esc_html( (string) $value );
     1098                $formatted = \esc_html( (string) $value );
    10991099            } else {
    11001100                // Fallback to escaped plain string.
    1101                 $formatted = esc_html( (string) $value );
     1101                $formatted = \esc_html( (string) $value );
    11021102            }
    11031103
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/traits/class-list-trait.php

    r3374674 r3380967  
    193193            }
    194194        }
     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        }
    195206    }
    196207}
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/views/class-requests-view.php

    r3375967 r3380967  
    6767                ? absint( $_REQUEST['trans_id'] )
    6868                : 0;
    69                 $transient    = Transients_Helper::get_transient_by_id( $transient_id );
     69                $transient    = Transients_Helper::get_transient_by_id( null,  $transient_id );
    7070                $name         = Transients_Helper::get_transient_name( $transient['option_name'] );
    7171                $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  
    208208                                    <p>
    209209                                        <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>
    211211                                    </p>
    212212                                    <div class="aadvana-panel-wrapper">
     
    217217                                                        <h3><?php \esc_html_e( 'Row data:', '0-day-analytics' ); ?></h3>
    218218                                                    </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>
    220220                                                </div>
    221221                                                <div class="http-request-args aadvana-pre-300" style="background: #fff;color:#000;">
     
    244244                        try {
    245245                            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 + '/',
    247247                                method: 'GET',
    248248                                cache: 'no-cache'
     
    273273
    274274                    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' ); ?>');
    276276                        //jQuery('.media-modal .table-name').html('');
    277277                        jQuery('.media-modal').removeClass('open');
     
    283283                        if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) {
    284284                            let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html();
    285 
    286                             console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())
    287285
    288286                            // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n");
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/views/class-transients-view.php

    r3374674 r3380967  
    1616use ADVAN\Helpers\WP_Helper;
    1717use ADVAN\Lists\Transients_List;
     18use ADVAN\ControllersApi\Endpoints;
    1819use ADVAN\Helpers\Transients_Helper;
    1920
     
    4041        public static function analytics_transients_page() {
    4142            \wp_enqueue_script( 'wp-api-fetch' );
     43            \wp_enqueue_style( 'media-views' );
     44            \wp_enqueue_script( 'wp-api-fetch' );
    4245            ?>
    4346            <script>
     
    6265                ? absint( $_REQUEST['trans_id'] )
    6366                : 0;
    64                 $transient    = Transients_Helper::get_transient_by_id( $transient_id );
     67                $transient    = Transients_Helper::get_transient_by_id( null, $transient_id );
    6568
    6669                if ( null !== $transient ) {
     
    7275
    7376                        $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' );
    7679                    }
    7780                }
     
    285288                    </form>
    286289                </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>
    287518                <?php
     519
    288520            }
    289521        }
  • 0-day-analytics/tags/3.8.0/classes/vendor/lists/views/class-wp-mail-view.php

    r3375967 r3380967  
    452452                            let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html();
    453453
    454                             console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())
    455 
    456454                            // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n");
    457455                            // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection
  • 0-day-analytics/tags/3.8.0/css/admin/style.css

    r3378902 r3380967  
    26642664html.aadvana-darkskin .wp-core-ui textarea:hover,
    26652665html.aadvana-darkskin .wp-core-ui textarea:focus,
    2666 html.aadvana-darkskin .wp-core-ui textarea:active {
     2666html.aadvana-darkskin .wp-core-ui textarea:active,
     2667html.aadvana-darkskin .wp-core-ui .dropdown-item {
    26672668  background-color: #062038;
    26682669  border-color: #383a3f;
  • 0-day-analytics/tags/3.8.0/js/admin/aadvana-settings.js

    r3357219 r3380967  
    242242    ------------------------------------------------------------------------------------------ */
    243243    $searchSettings = jQuery('#aadvana-panel-search'),
    244         $searchList = jQuery('#aadvana-search-list');
     244    $searchList0 = jQuery('#aadvana-search-list');
    245245
    246246    $searchSettings.on('keyup', function () {
    247247        var valThis = $searchSettings.val().toLowerCase();
    248         $searchList.html('');
     248        $searchList0.html('');
    249249
    250250        if (valThis == '') {
     
    265265                        thistextparentid = $thisparent.attr('id');
    266266
    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>');
    268268                }
    269269                else {
     
    274274    });
    275275
    276     $searchList.on('click', 'a', function () {
     276    $searchList0.on('click', 'a', function () {
    277277        var $thisElem = jQuery(this),
    278278            tabId = $thisElem.data('url'),
     
    292292
    293293        if (!container.is(e.target) && container.has(e.target).length === 0) {
    294             $searchList.html('');
     294            $searchList0.html('');
    295295            $searchSettings.val('');
    296296            jQuery('.highlights-search').removeClass('highlights-search');
  • 0-day-analytics/tags/3.8.0/readme.txt

    r3378902 r3380967  
    44Tested up to: 6.8
    55Requires PHP: 7.4
    6 Stable tag: 3.7.6
     6Stable tag: 3.8.0
    77License: GPLv3 or later
    88License URI: http://www.gnu.org/licenses/gpl-3.0.txt
     
    9696The 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.
    9797
    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 
    10198== Screenshots ==
    10299
     
    113110== Changelog ==
    114111
     112= 3.8.0 =
     113Added CSV export functionality to the modules. Code optimizations.
     114
    115115= 3.7.6 =
    116116Resolved 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  
    3131    'ADVAN\\Helpers\\File_Helper' => $baseDir . '/classes/vendor/helpers/class-file-helper.php',
    3232    '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',
    3334    'ADVAN\\Helpers\\PHP_Helper' => $baseDir . '/classes/vendor/helpers/class-php-helper.php',
    3435    '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  
    4646        'ADVAN\\Helpers\\File_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-file-helper.php',
    4747        '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',
    4849        'ADVAN\\Helpers\\PHP_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-php-helper.php',
    4950        'ADVAN\\Helpers\\Plugin_Theme_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-plugin-theme-helper.php',
  • 0-day-analytics/trunk/advanced-analytics.php

    r3378902 r3380967  
    1111 * Plugin Name:     0 Day Analytics
    1212 * Description:     Take full control of error log, crons, transients, plugins, requests, mails and DB tables.
    13  * Version:         3.7.6
     13 * Version:         3.8.0
    1414 * Author:          Stoil Dobrev
    1515 * Author URI:      https://github.com/sdobreff/
     
    3737// Constants.
    3838if ( ! defined( 'ADVAN_VERSION' ) ) {
    39     define( 'ADVAN_VERSION', '3.7.6' );
     39    define( 'ADVAN_VERSION', '3.8.0' );
    4040    define( 'ADVAN_TEXTDOMAIN', '0-day-analytics' );
    4141    define( 'ADVAN_NAME', '0 Day Analytics' );
     
    129129\add_action( 'wp_mail_failed', array( WP_Error_Handler::class, 'on_mail_error' ), -1 );
    130130
    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' );
    133133
    134134if ( ! WP_Helper::is_multisite() && \wp_is_recovery_mode() ) {
     
    220220         * Because of its extremely poor implementation, the log-iq plugin must be deactivated as it interferes very badly with the proper WP work.
    221221         */
    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        // }
    225225    }
    226226}
  • 0-day-analytics/trunk/classes/vendor/controllers/class-endpoints.php

    r3377720 r3380967  
    1616
    1717use ADVAN\Lists\Logs_List;
     18use ADVAN\Lists\WP_Mail_List;
    1819use ADVAN\Lists\Requests_List;
     20use ADVAN\Helpers\Crons_Helper;
     21use ADVAN\Helpers\Transients_Helper;
    1922use ADVAN\Entities_Global\Common_Table;
    20 use ADVAN\Helpers\Crons_Helper;
    21 use ADVAN\Lists\WP_Mail_List;
    2223
    2324defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
     
    242243                                        'pattern'     => '.+',
    243244                                        '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',
    244270                                    ),
    245271                                ),
  • 0-day-analytics/trunk/classes/vendor/entities/class-abstract-entity.php

    r3375967 r3380967  
    770770            return $results;
    771771        }
     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        }
    772783    }
    773784}
  • 0-day-analytics/trunk/classes/vendor/helpers/class-ajax-helper.php

    r3377720 r3380967  
    1212namespace ADVAN\Helpers;
    1313
     14use ADVAN\Lists\Logs_List;
    1415use ADVAN\Helpers\Settings;
     16use ADVAN\Lists\Crons_List;
     17use ADVAN\Lists\Table_List;
    1518use ADVAN\Controllers\Slack;
    1619use ADVAN\Helpers\WP_Helper;
     20use ADVAN\Lists\WP_Mail_List;
     21use ADVAN\Lists\Requests_List;
    1722use ADVAN\Controllers\Telegram;
    1823use ADVAN\Controllers\Error_Log;
     24use ADVAN\Controllers\Slack_API;
     25use ADVAN\Lists\Transients_List;
     26use ADVAN\Controllers\Telegram_API;
     27use ADVAN\Entities_Global\Common_Table;
    1928use ADVAN\Controllers\Mail_SMTP_Settings;
    20 use ADVAN\Controllers\Slack_API;
    21 use ADVAN\Controllers\Telegram_API;
    22 use ADVAN\Lists\Logs_List;
    2329
    2430// Exit if accessed directly.
     
    141147
    142148                \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' ) );
    143152            }
    144153        }
     
    650659            \wp_die();
    651660        }
     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        }
    652934    }
    653935}
  • 0-day-analytics/trunk/classes/vendor/helpers/class-settings.php

    r3374674 r3380967  
    306306                'wp-api-fetch'
    307307            );
     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.
    308345
    309346            ?>
  • 0-day-analytics/trunk/classes/vendor/helpers/class-transients-helper.php

    r3374674 r3380967  
    1515
    1616use ADVAN\Lists\Transients_List;
     17use ADVAN\Entities_Global\Common_Table;
    1718
    1819// Exit if accessed directly.
     
    148149         * Retrieve a transient by its ID
    149150         *
    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.
    151153         *
    152154         * @return array
    153155         *
    154156         * @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 ) {
    157160            global $wpdb;
    158161
     
    161164            // Bail if empty ID.
    162165            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                }
    164172            }
    165173
     
    168176
    169177            // 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            }
    171277        }
    172278
     
    334440                    $type = \esc_html__( 'json', '0-day-analytics' );
    335441                } 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' );
    337443
    338444                    // Scalar.
     
    392498
    393499            // Escape some LIKE parts.
    394             $esc_name = '' . $wpdb->esc_like( '_transient_' ) . '%';
     500            $esc_name      = '' . $wpdb->esc_like( '_transient_' ) . '%';
    395501            $esc_site_name = '' . $wpdb->esc_like( '_site_transient_' ) . '%';
    396             $esc_time = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%';
     502            $esc_time      = '%' . $wpdb->esc_like( '_transient_timeout_' ) . '%';
    397503
    398504            // SELECT.
     
    410516            // if ( empty( $parsed_args['count'] ) ) {
    411517
    412                 // FROM.
    413                
     518            // FROM.
     519
    414520            // old - ON d.option_name LIKE CONCAT('%_transient_timeout_', SUBSTRING_INDEX( go.option_name, '_transient_', -1 ), '%')
    415521
    416                 $sql[] = "LEFT JOIN
     522            $sql[] = "LEFT JOIN
    417523                {$wpdb->options} d
    418524                ON d.option_name = CONCAT(
     
    456562            if ( empty( $parsed_args['count'] ) && empty( $parsed_args['all'] ) ) {
    457563                $offset = absint( $parsed_args['offset'] );
    458                 $number = absint( $parsed_args['number'] );
     564                $per_page = absint( $parsed_args['per_page'] );
    459565
    460566                // if ( ! empty( $parsed_args['orderby'] ) && \in_array( $parsed_args['orderby'], array( 'transient_name' ) ) ) {
     
    475581                // );
    476582                // } 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 );
    478584                // }
    479585            }
     
    487593            // Query.
    488594            $transients = empty( $parsed_args['count'] )
    489                 ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    490                 : $wpdb->get_var( $prepared, 0 );    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
     595            ? $wpdb->get_results( $prepared, \ARRAY_A ) // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
     596            : $wpdb->get_var( $prepared, 0 );    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
    491597
    492598            if ( empty( $parsed_args['count'] ) && ! empty( $transients ) ) {
     
    496602                        'transient_name' => self::get_transient_name( $transient['option_name'] ),
    497603                        'value'          => self::get_transient_value( $transient['option_value'] ),
    498                         'schedule'       => (int) $transient['schedule'] ,
     604                        'schedule'       => (int) $transient['schedule'],
    499605                        'id'             => $transient['option_id'],
    500606                    );
  • 0-day-analytics/trunk/classes/vendor/lists/class-crons-list.php

    r3378902 r3380967  
    352352         *
    353353         * @since 1.1.0
    354          * @since 2.9.0 - Introduced flag getting the events wihtout the type filtering
     354         * @since 2.9.0 - Introduced flag getting the events without the type filtering
    355355         */
    356356        public static function get_cron_items( bool $no_type_filtering = false ): array {
     
    926926                    </select>
    927927                    <?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>
    928944                </div>
    929945                <?php
     
    11361152            return sprintf(
    11371153                $format,
    1138                 esc_attr( $link ),
    1139                 esc_html( $text ),
     1154                \esc_attr( $link ),
     1155                \esc_html( $text ),
    11401156                ( 'edit' )
    11411157            );
     
    12021218         * @since 1.4.0
    12031219         */
    1204         protected function get_table_classes() {
     1220        public function get_table_classes() {
    12051221            return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] );
    12061222        }
  • 0-day-analytics/trunk/classes/vendor/lists/class-logs-list.php

    r3377720 r3380967  
    11231123                            <?php
    11241124                    }
     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
    11251146                }
    11261147                ?>
     
    13451366                    </select>
    13461367                </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                            ?>
    13521374
    13531375                        <div id="advaa-filtering-notice" class="notice notice-info is-dismissible">
     
    13671389                            });
    13681390                        </script>
    1369                         <?php
    1370                     }
    1371                     ?>
     1391                            <?php
     1392                        }
     1393                        ?>
    13721394                <script>
    13731395
  • 0-day-analytics/trunk/classes/vendor/lists/class-requests-list.php

    r3375967 r3380967  
    1818use ADVAN\Helpers\WP_Helper;
    1919use ADVAN\Helpers\File_Helper;
    20 use ADVAN\Entities_Global\Common_Table;
     20use ADVAN\Helpers\Miscellaneous;
    2121use ADVAN\Lists\Traits\List_Trait;
    2222use ADVAN\ControllersApi\Endpoints;
     
    2424use ADVAN\Helpers\Plugin_Theme_Helper;
    2525use ADVAN\Entities\Requests_Log_Entity;
     26use ADVAN\Entities_Global\Common_Table;
    2627
    2728if ( ! class_exists( 'WP_List_Table' ) ) {
     
    207208            $this->handle_table_actions();
    208209
    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            );
    210249
    211250            $columns = self::manage_columns( array() );
     
    282321         * Fetch table data from the WordPress database.
    283322         *
     323         * @param array $args - The arguments collected / passed.
     324         *
    284325         * @since 1.0.0
     326         * @since latest - added $args param.
    285327         *
    286328         * @return  Array
    287329         */
    288         public function fetch_table_data() {
     330        public function fetch_table_data( array $args = array() ) {
    289331
    290332            global $wpdb;
    291333
    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'];
    312357
    313358            $search_sql = '';
     
    315360            if ( '' !== $search_string ) {
    316361                $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 ) {
    318363                    $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" ';
    319364                }
     
    321366            }
    322367
    323             if ( '' !== $plugin && -1 !== (int) $plugin ) {
     368            if ( '' !== $plugin && -1 !== (int) $plugin && 0 !== (int) $plugin ) {
    324369                $search_sql .= ' AND plugin = "' . (string) $plugin . '" ';
    325370            }
     
    327372            $wpdb_table = $this->get_table_name();
    328373
    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
    332375                ' . implode( ', ', \array_keys( Requests_Log_Entity::get_fields() ) ) . '
    333376              FROM ' . $wpdb_table . '  WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order;
     
    757800                </script>
    758801                <?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                }
    760823                if ( 'top' === $which ) {
    761824                    ?>
    762825                <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(); ?>
    799827                    /* .wp-list-table {
    800828                        display: block;
  • 0-day-analytics/trunk/classes/vendor/lists/class-table-list.php

    r3377720 r3380967  
    1818use ADVAN\Helpers\WP_Helper;
    1919use ADVAN\Helpers\File_Helper;
    20 use ADVAN\Entities_Global\Common_Table;
     20use ADVAN\Helpers\Miscellaneous;
    2121use ADVAN\Lists\Views\Table_View;
    2222use ADVAN\Lists\Traits\List_Trait;
     23use ADVAN\Entities_Global\Common_Table;
    2324
    2425if ( ! class_exists( 'WP_List_Table' ) ) {
     
    164165            $this->handle_table_actions();
    165166
    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            );
    167195
    168196            $columns = self::$table::manage_columns( array() );
     
    209237         * @return array
    210238         */
    211         protected function get_sortable_columns() {
     239        public function get_sortable_columns() {
    212240            $first6_columns = array_keys( self::$table::get_column_names_admin() );
    213241
     
    239267         * Fetch table data from the WordPress database.
    240268         *
     269         * @param array $args - The arguments collected / passed.
     270         *
    241271         * @since 1.0.0
     272         * @since latest - added $args param.
    242273         *
    243274         * @return  Array
    244275         */
    245         public function fetch_table_data() {
     276        public function fetch_table_data( array $args = array() ) {
    246277
    247278            global $wpdb;
    248279
    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'];
    259300
    260301            $search_sql = '';
     
    268309            }
    269310
    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
    275312                ' . implode( ', ', self::$table::get_column_names() ) . '
    276313              FROM ' . $wpdb_table . '  WHERE 1=1 ' . $search_sql . ' ORDER BY ' . $orderby . ' ' . $order;
     
    279316
    280317            // 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
    284321
    285322            // return result array to prepare_items.
     
    585622               
    586623            </div>
    587 
    588624            <?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            }
    589646            // if ( 'top' === $which ) {
    590647            global $wpdb;
    591648            ?>
    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>
    598816                        <?php
    599817                        if ( 'top' === $which ) {
    600818                            ?>
    601819                <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(); ?>
    638821                    /* .wp-list-table {
    639822                        display: block;
     
    650833                        top: 0;
    651834                    } */
    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>
    654920                        <?php } ?>
    655921                <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  
    1919use ADVAN\Helpers\WP_Helper;
    2020use ADVAN\Helpers\Crons_Helper;
     21use ADVAN\Helpers\Miscellaneous;
    2122use ADVAN\Lists\Traits\List_Trait;
    2223use ADVAN\Helpers\Transients_Helper;
     
    276277            $this->fetch_table_data(
    277278                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,
    284285                )
    285286            );
     
    327328         * @return array
    328329         */
    329         protected function get_sortable_columns() {
     330        public function get_sortable_columns() {
    330331            // Currently there is no way to implement sorting because of the way they are stored in the database.
    331332            return array(
     
    377378                $args,
    378379                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,
    383384                )
    384385            );
     
    451452
    452453                    $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>';
    453456
    454457                    $edit_url = \remove_query_arg(
     
    591594
    592595                ?>
    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>
    596599                <?php
    597600            }
     
    689692                </script>
    690693                <style>
     694                    <?php echo Miscellaneous::get_flex_style(); ?>
    691695                    .generated-transients .persistent th:nth-child(1) {
    692696                        border-left: 7px solid #d2ab0e !important;
     
    711715            }
    712716            $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
    713739            $this->pagination( $which );
    714740
     
    772798         * @since 1.4.0
    773799         */
    774         protected function get_table_classes() {
     800        public function get_table_classes() {
    775801            return array( 'widefat', 'striped', 'table-view-list', $this->_args['plural'] );
    776802        }
  • 0-day-analytics/trunk/classes/vendor/lists/class-wp-mail-list.php

    r3378902 r3380967  
    2121use ADVAN\Controllers\WP_Mail_Log;
    2222use ADVAN\Entities\WP_Mail_Entity;
     23use ADVAN\Helpers\Miscellaneous;
    2324use ADVAN\Lists\Traits\List_Trait;
    2425use ADVAN\Lists\Views\WP_Mail_View;
     
    249250            $items = $this->fetch_table_data(
    250251                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,
    258259                )
    259260            );
     
    346347                $args,
    347348                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,
    355356                )
    356357            );
     
    368369            if ( ! isset( $parsed_args['all'] ) ) {
    369370
    370                 $per_page = $parsed_args['number'];
     371                $per_page = $parsed_args['per_page'];
    371372                $offset   = $parsed_args['offset'];
    372373
     
    383384                if ( '' !== $search_string ) {
    384385                    $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 ) {
    386387                        $search_sql .= ' OR ' . $value . ' LIKE "%' . esc_sql( $wpdb->esc_like( $search_string ) ) . '%" ';
    387388                    }
     
    10931094                <?php
    10941095            }
     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            }
    10951117            if ( 'top' === $which ) {
    10961118                ?>
    10971119                <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(); ?>
    11341121                    /* .wp-list-table {
    11351122                        display: block;
  • 0-day-analytics/trunk/classes/vendor/lists/entity/class-common-table.php

    r3378902 r3380967  
    996996            $wpdb->suppress_errors( true );
    997997
    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
    999999
    10001000            if ( '' !== $wpdb->last_error || null === $results ) {
     
    10661066         * @since latest
    10671067         */
    1068         private static function format_value_for_html( $value ) {
     1068        public static function format_value_for_html( $value ) {
    10691069            // Try to decode JSON if it's a string.
    10701070            if ( is_string( $value ) ) {
     
    10961096                $formatted = '<em>null</em>';
    10971097            } elseif ( is_numeric( $value ) ) {
    1098                 $formatted = esc_html( (string) $value );
     1098                $formatted = \esc_html( (string) $value );
    10991099            } else {
    11001100                // Fallback to escaped plain string.
    1101                 $formatted = esc_html( (string) $value );
     1101                $formatted = \esc_html( (string) $value );
    11021102            }
    11031103
  • 0-day-analytics/trunk/classes/vendor/lists/traits/class-list-trait.php

    r3374674 r3380967  
    193193            }
    194194        }
     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        }
    195206    }
    196207}
  • 0-day-analytics/trunk/classes/vendor/lists/views/class-requests-view.php

    r3375967 r3380967  
    6767                ? absint( $_REQUEST['trans_id'] )
    6868                : 0;
    69                 $transient    = Transients_Helper::get_transient_by_id( $transient_id );
     69                $transient    = Transients_Helper::get_transient_by_id( null,  $transient_id );
    7070                $name         = Transients_Helper::get_transient_name( $transient['option_name'] );
    7171                $expiration   = Transients_Helper::get_transient_expiration_time( $transient['option_name'] );
  • 0-day-analytics/trunk/classes/vendor/lists/views/class-table-view.php

    r3377720 r3380967  
    208208                                    <p>
    209209                                        <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>
    211211                                    </p>
    212212                                    <div class="aadvana-panel-wrapper">
     
    217217                                                        <h3><?php \esc_html_e( 'Row data:', '0-day-analytics' ); ?></h3>
    218218                                                    </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>
    220220                                                </div>
    221221                                                <div class="http-request-args aadvana-pre-300" style="background: #fff;color:#000;">
     
    244244                        try {
    245245                            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 + '/',
    247247                                method: 'GET',
    248248                                cache: 'no-cache'
     
    273273
    274274                    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' ); ?>');
    276276                        //jQuery('.media-modal .table-name').html('');
    277277                        jQuery('.media-modal').removeClass('open');
     
    283283                        if ( jQuery(this).parent().parent().next('.aadvana-pre-300') ) {
    284284                            let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html();
    285 
    286                             console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())
    287285
    288286                            // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n");
  • 0-day-analytics/trunk/classes/vendor/lists/views/class-transients-view.php

    r3374674 r3380967  
    1616use ADVAN\Helpers\WP_Helper;
    1717use ADVAN\Lists\Transients_List;
     18use ADVAN\ControllersApi\Endpoints;
    1819use ADVAN\Helpers\Transients_Helper;
    1920
     
    4041        public static function analytics_transients_page() {
    4142            \wp_enqueue_script( 'wp-api-fetch' );
     43            \wp_enqueue_style( 'media-views' );
     44            \wp_enqueue_script( 'wp-api-fetch' );
    4245            ?>
    4346            <script>
     
    6265                ? absint( $_REQUEST['trans_id'] )
    6366                : 0;
    64                 $transient    = Transients_Helper::get_transient_by_id( $transient_id );
     67                $transient    = Transients_Helper::get_transient_by_id( null, $transient_id );
    6568
    6669                if ( null !== $transient ) {
     
    7275
    7376                        $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' );
    7679                    }
    7780                }
     
    285288                    </form>
    286289                </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>
    287518                <?php
     519
    288520            }
    289521        }
  • 0-day-analytics/trunk/classes/vendor/lists/views/class-wp-mail-view.php

    r3375967 r3380967  
    452452                            let selectedText = jQuery(this).parent().parent().next('.aadvana-pre-300').html();
    453453
    454                             console.log(jQuery(this).parent().parent().next('.aadvana-pre-300').html())
    455 
    456454                            // selectedText = selectedText.replace(/<br\s*\/?>/gim, "\n");
    457455                            // selectedText = jQuery.parseHTML(selectedText); //parseHTML return HTMLCollection
  • 0-day-analytics/trunk/css/admin/style.css

    r3378902 r3380967  
    26642664html.aadvana-darkskin .wp-core-ui textarea:hover,
    26652665html.aadvana-darkskin .wp-core-ui textarea:focus,
    2666 html.aadvana-darkskin .wp-core-ui textarea:active {
     2666html.aadvana-darkskin .wp-core-ui textarea:active,
     2667html.aadvana-darkskin .wp-core-ui .dropdown-item {
    26672668  background-color: #062038;
    26682669  border-color: #383a3f;
  • 0-day-analytics/trunk/js/admin/aadvana-settings.js

    r3357219 r3380967  
    242242    ------------------------------------------------------------------------------------------ */
    243243    $searchSettings = jQuery('#aadvana-panel-search'),
    244         $searchList = jQuery('#aadvana-search-list');
     244    $searchList0 = jQuery('#aadvana-search-list');
    245245
    246246    $searchSettings.on('keyup', function () {
    247247        var valThis = $searchSettings.val().toLowerCase();
    248         $searchList.html('');
     248        $searchList0.html('');
    249249
    250250        if (valThis == '') {
     
    265265                        thistextparentid = $thisparent.attr('id');
    266266
    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>');
    268268                }
    269269                else {
     
    274274    });
    275275
    276     $searchList.on('click', 'a', function () {
     276    $searchList0.on('click', 'a', function () {
    277277        var $thisElem = jQuery(this),
    278278            tabId = $thisElem.data('url'),
     
    292292
    293293        if (!container.is(e.target) && container.has(e.target).length === 0) {
    294             $searchList.html('');
     294            $searchList0.html('');
    295295            $searchSettings.val('');
    296296            jQuery('.highlights-search').removeClass('highlights-search');
  • 0-day-analytics/trunk/readme.txt

    r3378902 r3380967  
    44Tested up to: 6.8
    55Requires PHP: 7.4
    6 Stable tag: 3.7.6
     6Stable tag: 3.8.0
    77License: GPLv3 or later
    88License URI: http://www.gnu.org/licenses/gpl-3.0.txt
     
    9696The 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.
    9797
    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 
    10198== Screenshots ==
    10299
     
    113110== Changelog ==
    114111
     112= 3.8.0 =
     113Added CSV export functionality to the modules. Code optimizations.
     114
    115115= 3.7.6 =
    116116Resolved 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  
    3131    'ADVAN\\Helpers\\File_Helper' => $baseDir . '/classes/vendor/helpers/class-file-helper.php',
    3232    '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',
    3334    'ADVAN\\Helpers\\PHP_Helper' => $baseDir . '/classes/vendor/helpers/class-php-helper.php',
    3435    '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  
    4646        'ADVAN\\Helpers\\File_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-file-helper.php',
    4747        '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',
    4849        'ADVAN\\Helpers\\PHP_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-php-helper.php',
    4950        'ADVAN\\Helpers\\Plugin_Theme_Helper' => __DIR__ . '/../..' . '/classes/vendor/helpers/class-plugin-theme-helper.php',
Note: See TracChangeset for help on using the changeset viewer.