403Webshell
Server IP : _  /  Your IP : 169.254.129.1
Web Server : nginx/1.28.0
System : Linux 89e302d72aa1 6.6.143.1-1.azl3 #1 SMP PREEMPT_DYNAMIC Mon Jul 6 04:01:14 UTC 2026 x86_64
User : nginx ( 103)
PHP Version : 8.2.30
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/wordpress/wp-content/plugins/posts-table-pro/includes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/wordpress/wp-content/plugins/posts-table-pro/includes/class-posts-data-table.php
<?php

// Prevent direct file access
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * The main Posts_Data_Table class.
 *
 * Responsible for creating the posts table from the specified args and returning the
 * complete table as a Html_Data_Table instance.
 *
 * The main functions are get_table() and get_data().
 *
 * @package   Posts_Table_Pro
 * @author    Barn2 Media <info@barn2.co.uk>
 * @license   GPL-3.0
 * @copyright Barn2 Media Ltd
 */
class Posts_Data_Table {

    public $id;

    /* Helper classes */
    public $args;
    public $query;
    public $hooks;
    public $data_table;
    private $columns;
    private $data_factory;
    private $config_builder;
    private $cache;

    /* Internal flags */
    private $table_initialised = false;
    private $data_added        = false;

    const CONTROL_COLUMN_DATA_SOURCE = 'control';

    public function __construct( $id, $args = array() ) {
        $this->id = $id;

        // Initialize helper classes
        $this->args           = new Posts_Table_Args( $args );
        $this->query          = new Posts_Table_Query( $this->args );
        $this->columns        = new Posts_Table_Columns( $this->args );
        $this->data_factory   = new Posts_Table_Data_Factory( $this->args );
        $this->hooks          = new Posts_Table_Hook_Manager( $this->args );
        $this->config_builder = new Posts_Table_Config_Builder( $this->id, $this->args, $this->columns );
        $this->cache          = new Posts_Table_Cache( $this->id, $this->args, $this->query );
        $this->data_table     = new Html_Data_Table();
    }

    /**
     * Retrieves the data table containing the list of posts based on the arguments
     * supplied on construction.
     *
     * The table returned includes the table headings, attributes and data.
     *
     * If the output is 'object' the returned object is an Html_Data_Table instance.
     * If the output is 'html', the table returned will be a string containing the <table> element
     * at its root, and include the <thead>, <tfoot> and <tbody> elements.
     * If the output is 'array', the table returned will be an array containing the following keys:
     * 'thead', 'tbody', 'tfoot' and 'attributes'.
     * If the output is 'json', the return value will be a JSON-encoded string in the same format
     * as 'array'.
     *
     * @param string $output The output format - object, html, array or json. Default 'object'.
     * @return object|array|string The posts table in the requested format.
     */
    public function get_table( $output = 'object' ) {

        if ( ! $this->table_initialised ) {
            // Add table to cache.
            $this->cache->add_table();

            // Reset the table
            $this->data_table->reset();

            do_action( 'posts_table_before_get_table', $this );

            // Register scripts for this table.
            Posts_Table_Frontend_Scripts::register_table_scripts( $this->args );

            // Add attriutes and table headings.
            $this->add_attributes();
            $this->add_headings();

            // Fetch the data.
            $this->fetch_data();

            // @deprecated 2.0 - Replaced by 'posts_table_after_get_table'.
            do_action( 'posts_table_get_table', $this );

            do_action( 'posts_table_after_get_table', $this );

            $this->table_initialised = true;
        }

        $result = $this->data_table;

        if ( 'html' === $output ) {
            $result = $this->data_table->to_html();
        } elseif ( 'array' === $output ) {
            $result = $this->data_table->to_array();
        } elseif ( 'json' === $output ) {
            $result = $this->data_table->to_json();
        }

        return apply_filters( 'posts_table_get_table_output', $result, $output, $this );
    }

    /**
     * Retrieves the data table containing the list of posts based on the specified arguments.
     *
     * The table returned includes only the table data itself (i.e. the rows), and doesn't include the header, footer, etc.
     *
     * If the output is 'object' the returned object will be an Html_Data_Table instance.
     * If the output is 'html', the data returned will be a string containing a list of <tr> elements,
     * one for each product found.
     * If the output is 'array', the data returned will be an array of rows, one for each product found.
     * if the output is 'json', the data returned will be a JSON-encoded string in the same format
     * as 'array'.
     *
     * @return object|array|string The posts table data in the requested format.
     */
    public function get_data( $output = 'object' ) {
        // Fetch the data.
        $this->fetch_data();

        $result = $this->data_table;

        // Build the output.
        if ( 'html' === $output ) {
            $result = $this->data_table->to_html( true );
        } elseif ( 'array' === $output ) {
            $result = $this->data_table->to_array( true );
        } elseif ( 'json' === $output ) {
            $result = $this->data_table->to_json( true );
        }

        return apply_filters( 'posts_table_get_data_output', $result, $output, $this );
    }

    public function update( array $new_args ) {
        $this->table_initialised = false;
        $this->data_added        = false;

        // Work out what changed
        $args_changed = array_keys( Posts_Table_Util::array_diff_assoc( $new_args, get_object_vars( $this->args ) ) );

        if ( array_intersect( $args_changed, array( 'post_type', 'status', 'year', 'month', 'day', 'category', 'tag', 'term', 'cf', 'author', 'exclude',
                'include', 'exclude_category', 'search_term' ) ) ) {
            // If any of the post paramaters are updated, reset posts array and totals
            $this->query->set_posts( null );
            $this->query->set_total_posts( null );
            $this->query->set_total_filtered_posts( null );
        } elseif ( array_intersect( $args_changed, array( 'rows_per_page', 'post_limit', 'offset', 'sort_by', 'sort_order' ) ) ) {
            // If just the table paramaters are updated, reset posts but not totals
            $this->query->set_posts( null );
        }

        if ( array_intersect( $args_changed, array( 'search_filters' ) ) ) {
            // If the search  filters changed from last time, reset posts array and filtered total, but leave the overall total.
            $this->query->set_posts( null );
            $this->query->set_total_filtered_posts( null );
        }

        // Don't use cache if lazy loading and query params have been modified (e.g. rows_per_page, sort_by, etc)
        // We don't check offset here as we cache each page of results separately using offset in the cache key
        if ( $this->args->lazy_load && array_intersect( $args_changed, array( 'status', 'year', 'month', 'day', 'category', 'tag', 'term', 'cf', 'author',
                'exclude', 'include', 'exclude_category', 'rows_per_page', 'post_limit', 'sort_by', 'sort_order', 'search_term', 'search_filters' ) ) ) {
            $new_args['cache'] = false;
        }

        // Finally, we update the args - this will update the args object in all helper classes as objects are stored by reference.
        $this->args->set_args( $new_args );

        do_action( 'posts_table_args_updated', $this );
    }

    private function fetch_data() {
        if ( $this->data_added || ! $this->can_fetch_data() ) {
            return;
        }

        // Reset the table data
        $this->data_table->reset_data();

        if ( $data = $this->cache->get_data() ) {
            $this->data_table->set_data( $data );
        } else {
            // No cache found or caching disabled...
            do_action( 'posts_table_before_get_data', $this );

            // Register the data hooks.
            $this->hooks->register();

            // Add all posts to the table.
            $this->add_posts_to_table( $this->query->get_posts() );

            // Reset hooks.
            $this->hooks->reset();

            // Update caches.
            $this->cache->update_table( true );
            $this->cache->update_data( $this->data_table->get_data() );

            // @deprecated 2.0 - Replaced by 'posts_table_after_get_data'.
            do_action( 'posts_table_get_data', $this );

            do_action( 'posts_table_after_get_data', $this );
        }

        $this->data_added = true;
    }

    private function can_fetch_data() {
        if ( ! $this->args->lazy_load ) {
            return true;
        } else {
            return $this->args->lazy_load && defined( 'DOING_AJAX' ) && DOING_AJAX;
        }
    }

    private function add_posts_to_table( $posts ) {
        if ( ! $posts ) {
            return;
        }

        // To make absolutely sure the global $post gets reset, we store it here and set it back after our posts loop
        $old_global_post = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : false;

        $cols = $this->columns->get_all_columns();

        // Loop through posts and add post data
        foreach ( $posts as $_post ) {
            // Set post global as needed for certain calls, e.g. get_the_content()
            $GLOBALS['post'] = $_post;

            // Setup global post data (id, authordata, etc).
            setup_postdata( $_post );

            $this->data_table->new_row( $this->get_row_attributes( $_post ) );

            // Add empty cell if we're using the control column for responsive child rows
            if ( 'column' === $this->args->responsive_control ) {
                $this->data_table->add_data( '', false, self::CONTROL_COLUMN_DATA_SOURCE );
            }

            // Add the data for this post
            array_walk( $cols, array( $this, 'add_post_data' ), $_post );
        }

        // Reset main WP query as we called setup_postdata
        if ( $old_global_post ) {
            $GLOBALS['post'] = $old_global_post;
        }

        wp_reset_postdata();
    }

    private function add_post_data( $column, $key, $post ) {
        $data = '';
        $atts = false;

        // Get data object for this column
        if ( $data_obj = $this->data_factory->create( $column, $post ) ) {
            $data = $data_obj->get_data();
            $atts = array_filter(
                array(
                    'data-sort'   => $data_obj->get_sort_data(),
                    'data-filter' => $data_obj->get_filter_data()
                ),
                array( __CLASS__, 'array_filter_empty_attribute' )
            );
        } else {
            // Back compat: data object not found (e.g. custom column) so run filter
            $data = apply_filters( 'posts_table_custom_data_' . $column, '', $post );
            $atts = apply_filters( 'posts_table_custom_data_atts_' . $column, false, $post );
        }

        // @deprecated 2.0 - Replaced by individual column filters.
        $data = apply_filters( 'posts_table_cell_data_' . Posts_Table_Columns::unprefix_column( $column ), $data, $post );

        $this->data_table->add_data( $data, $atts, Posts_Table_Columns::get_column_data_source( $column ) );
    }

    private function add_attributes() {
        // Set table attributes.
        $table_class = trim( 'posts-data-table ' . ( $this->args->wrap ? '' : 'nowrap ' ) . apply_filters( 'posts_table_custom_class', '', $this ) );

        $this->data_table->add_attribute( 'id', $this->id );
        $this->data_table->add_attribute( 'class', $table_class );

        // This is required otherwise tables can expand beyond their container.
        $this->data_table->add_attribute( 'width', '100%' );

        // Add the table config as JSON encoded data.
        $this->data_table->add_attribute( 'data-config', htmlspecialchars( self::json_encode_config( $this->config_builder->get_config() ) ) );
        $this->data_table->add_attribute( 'data-filters', htmlspecialchars( wp_json_encode( $this->config_builder->get_filters() ) ) );

        // Set table ordering during initialisation - default to no ordering (i.e. use post order returned from WP_Query).
        $order_attr = '[]';

        // If column is sortable, set initial sort order for DataTables.
        if ( $this->columns->is_sortable( $this->args->sort_by ) ) {
            $sort_index = $this->columns->column_index( $this->args->sort_by );

            if ( false !== $sort_index ) {
                // 'sort_order' has to be in double quotes (@see https://datatables.net/manual/options).
                $order_attr = sprintf( '[[%u, "%s"]]', $sort_index, $this->args->sort_order );
            }
        }
        $this->data_table->add_attribute( 'data-order', $order_attr );
    }

    private function add_headings() {
        // Add the control column for responsive layouts if required (the column that contains the + / - icon)
        if ( 'column' === $this->args->responsive_control ) {
            $this->add_heading( '', array( 'data-data' => self::CONTROL_COLUMN_DATA_SOURCE ), self::CONTROL_COLUMN_DATA_SOURCE );
        }

        // Add column headings
        foreach ( $this->columns->get_columns() as $i => $column ) {
            $data_source = Posts_Table_Columns::get_column_data_source( $column );

            $column_atts = array(
                'class'           => $this->columns->get_column_heading_class( $i, $column ),
                'data-name'       => Posts_Table_Columns::get_column_name( $column ),
                'data-orderable'  => $this->columns->is_sortable( $column ),
                'data-searchable' => $this->columns->is_searchable( $column ),
                'data-width'      => $this->columns->get_column_width( $i, $column ),
                'data-priority'   => $this->columns->get_column_priority( $i, $column )
            );

            if ( $this->args->lazy_load ) {
                // Data source required only for lazy load.
                $column_atts['data-data'] = $data_source;
            }
            if ( $this->columns->is_click_filterable( $column ) ) {
                //@todo: Remove this
                $column_atts['data-click-filter'] = true;
            }

            $this->add_heading( $this->columns->get_column_heading( $i, $column ), $column_atts, $data_source );
        }

        // Add hidden columns
        foreach ( $this->columns->get_hidden_columns() as $column ) {
            $data_source = Posts_Table_Columns::get_column_data_source( $column );

            $column_atts = array(
                'data-name'       => Posts_Table_Columns::get_column_name( $column ),
                'data-tax'        => Posts_Table_Columns::get_column_taxonomy( $column ),
                'data-searchable' => true,
                'data-visible'    => $this->args->show_hidden
            );

            if ( $this->args->lazy_load ) {
                // Data source required only for lazy load.
                $column_atts['data-data'] = $data_source;
            }

            $this->add_heading( $column, $column_atts, $data_source );
        }
    }

    private function add_heading( $heading, $attributes, $key ) {
        $this->data_table->add_header( $heading, $attributes, $key );

        if ( $this->args->show_footer ) {
            $this->data_table->add_footer( $heading, false, $key ); // attributes not needed in footer.
        }
    }

    private function get_row_attributes( $post ) {
        $classes = array(
            'post-row',
            'post-type-' . $post->post_type,
            $post->post_type . '-' . $post->ID,
            $post->post_status
        );


        $row_attributes = array(
            'id'    => 'post-row-' . $post->ID,
            'class' => implode( ' ', array_map( 'sanitize_html_class', apply_filters( 'posts_table_row_class', $classes, $post ) ) )
        );

        return apply_filters( 'posts_table_row_attributes', $row_attributes, $post );
    }

    private static function array_filter_empty_attribute( $value ) {
        return ( '' === $value ) ? false : true;
    }

    private static function json_encode_config( $config ) {
        $json_config = wp_json_encode( $config );

        // Ensure JS functions are defined as a function, not a string, in the encoded json
        return preg_replace( '#"(jQuery\.fn.*)"#U', '$1', $json_config );
    }

}

// class Posts_Data_Table

Youez - 2016 - github.com/yon3zu
LinuXploit