WordPress.org

Make WordPress Core

Ticket #19815: 19815.11.diff

File 19815.11.diff, 10.9 KB (added by mikeschroder, 6 years ago)

Added JSON passing of necessary variables and removed parseQuery. Added $this->features to theme-install list table and removed $term global. Additional error handling.

  • wp-admin/includes/class-wp-theme-install-list-table.php

     
    99 */
    1010class WP_Theme_Install_List_Table extends WP_List_Table {
    1111
     12        var $features = array();
     13
    1214        function __construct() {
    1315                parent::__construct( array(
    1416                        'ajax' => true,
     
    1618        }
    1719
    1820        function ajax_user_can() {
    19                 return current_user_can('install_themes');
     21                return current_user_can( 'install_themes' );
    2022        }
    2123
    2224        function prepare_items() {
    2325                include( ABSPATH . 'wp-admin/includes/theme-install.php' );
    2426
    25                 global $tabs, $tab, $paged, $type, $term, $theme_field_defaults;
    26 
     27                global $tabs, $tab, $paged, $type, $theme_field_defaults;
    2728                wp_reset_vars( array( 'tab' ) );
    2829
     30                $search = array();
     31                $sanitized_terms = '';
     32                if ( ! empty( $_REQUEST['s'] ) ) {
     33                        $sanitized_terms = strtolower( stripslashes( $_REQUEST['s'] ) );
     34                        $search = array_merge( $search, array_filter( array_map( 'trim', explode( ',', $sanitized_terms ) ) ) );
     35                        $search = array_unique( $search );
     36                }
     37
     38                if ( ! empty( $_REQUEST['features'] ) ) {
     39                        $this->features = $_REQUEST['features'];
     40                        $this->features = array_map( 'trim', $this->features );
     41                        $this->features = array_map( 'sanitize_title_with_dashes', $this->features );
     42                        $this->features = array_unique( $this->features );
     43                }
     44
    2945                $paged = $this->get_pagenum();
    3046
    3147                $per_page = 36;
     
    5571                switch ( $tab ) {
    5672                        case 'search':
    5773                                $type = isset( $_REQUEST['type'] ) ? stripslashes( $_REQUEST['type'] ) : '';
    58                                 $term = isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '';
    59 
    6074                                switch ( $type ) {
    6175                                        case 'tag':
    62                                                 $terms = explode( ',', $term );
    63                                                 $terms = array_map( 'trim', $terms );
    64                                                 $terms = array_map( 'sanitize_title_with_dashes', $terms );
    65                                                 $args['tag'] = $terms;
     76                                                $args['tag'] = array_map( 'sanitize_title_with_dashes', $search );
    6677                                                break;
    6778                                        case 'term':
    68                                                 $args['search'] = $term;
     79                                                $args['search'] = $sanitized_terms;
    6980                                                break;
    7081                                        case 'author':
    71                                                 $args['author'] = $term;
     82                                                $args['author'] = $sanitized_terms;
    7283                                                break;
    7384                                }
    7485
    75                                 if ( !empty( $_REQUEST['features'] ) ) {
    76                                         $terms = $_REQUEST['features'];
    77                                         $terms = array_map( 'trim', $terms );
    78                                         $terms = array_map( 'sanitize_title_with_dashes', $terms );
    79                                         $args['tag'] = $terms;
    80                                         $_REQUEST['s'] = implode( ',', $terms );
     86                                if ( ! empty( $this->features ) ) {
     87                                        $args['tag'] = $this->features;
     88                                        $_REQUEST['s'] = implode( ',', $this->features );
    8189                                        $_REQUEST['type'] = 'tag';
    8290                                }
    8391
     
    95103                                $args = false;
    96104                }
    97105
    98                 if ( !$args )
     106                if ( ! $args )
    99107                        return;
    100108
    101109                $api = themes_api( 'query_themes', $args );
     
    170178                                ?></div>
    171179                <?php } // end foreach $theme_names
    172180        }
     181
     182        /**
     183         * Send required variables to JavaScript land
     184         *
     185         * @since 3.4
     186         * @access private
     187         *
     188         * @uses $tab Global; current tab within Themes->Install screen
     189         * @uses $type Global; type of search.
     190         * @uses $this->features Array of all feature search terms.
     191         * @uses get_pagenum()
     192         * @uses _pagination_args['total_pages']
     193         */
     194        function _js_vars() {
     195                global $tab, $type;
     196                $search_string = isset( $_REQUEST['s'] ) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
     197
     198                $total_pages = 0;
     199                if ( ! empty( $this->_pagination_args['total_pages'] ) )
     200                        $total_pages = $this->_pagination_args['total_pages'];
     201
     202                $args = array(
     203                        'search' => $search_string,
     204                        'features' => $this->features,
     205                        'paged' => $this->get_pagenum(),
     206                        'total_pages' => $total_pages,
     207
     208                        // Send items specific to theme-install
     209                        'tab' => $tab,
     210                        'type' => $type,
     211                );
     212
     213                printf( "<script type='text/javascript'>theme_list_args = %s;</script>\n", json_encode( $args ) );
     214                parent::_js_vars();
     215        }
    173216}
  • wp-admin/includes/class-wp-themes-list-table.php

     
    1111
    1212        var $search = array();
    1313        var $features = array();
    14        
     14
    1515        function __construct() {
    1616                parent::__construct( array(
    1717                        'ajax' => true,
     
    2020
    2121        function ajax_user_can() {
    2222                // Do not check edit_theme_options here. AJAX calls for available themes require switch_themes.
    23                 return current_user_can('switch_themes');
     23                return current_user_can( 'switch_themes' );
    2424        }
    2525
    2626        function prepare_items() {
     
    3232                        $this->search = array_unique( $this->search );
    3333                }
    3434
    35                 if ( !empty( $_REQUEST['features'] ) ) {
     35                if ( ! empty( $_REQUEST['features'] ) ) {
    3636                        $this->features = $_REQUEST['features'];
    3737                        $this->features = array_map( 'trim', $this->features );
    3838                        $this->features = array_map( 'sanitize_title_with_dashes', $this->features );
     
    217217
    218218                return true;
    219219        }
     220
     221        /**
     222         * Send required variables to JavaScript land
     223         *
     224         * @since 3.4
     225         * @access private
     226         *
     227         * @uses $this->features Array of all feature search terms.
     228         * @uses get_pagenum()
     229         * @uses _pagination_args['total_pages']
     230         */
     231         function _js_vars() {
     232                $search_string = isset( $_REQUEST['s'] ) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
     233
     234                $total_pages = 1;
     235                if ( ! empty( $this->_pagination_args['total_pages'] ) )
     236                        $total_pages = $this->_pagination_args['total_pages'];
     237
     238                $args = array(
     239                        'search' => $search_string,
     240                        'features' => $this->features,
     241                        'paged' => $this->get_pagenum(),
     242                        'total_pages' => $total_pages,
     243                );
     244
     245                printf( "<script type='text/javascript'>theme_list_args = %s;</script>\n", json_encode( $args ) );
     246                parent::_js_vars();
     247        }
    220248}
  • wp-admin/js/theme.dev.js

     
    5454        theme_viewer.init();
    5555});
    5656
     57
     58/**
     59 * Class that provides infinite scroll for Themes admin screens
     60 *
     61 * @since 3.4
     62 *
     63 * @uses ajaxurl
     64 * @uses list_args
     65 * @uses theme_list_args
     66 * @uses $('#_ajax_fetch_list_nonce').val()
     67* */
    5768var ThemeScroller;
    58 
    5969(function($){
    6070        ThemeScroller = {
    61                 // Inputs
    6271                nonce: '',
    63                 search: '',
    64                 tab: '',
    65                 type: '',
    66                 nextPage: 2,
    67                 features: {},
    68 
    69                 // Preferences
     72                nextPage: 2, // By default, assume we're on the first page.
     73                querying: false,
    7074                scrollPollingDelay: 500,
    7175                failedRetryDelay: 4000,
    7276                outListBottomThreshold: 300,
    7377
    74                 // Flags
    75                 scrolling: false,
    76                 querying: false,
    77 
     78                /**
     79                 * Initializer
     80                 *
     81                 * @since 3.4
     82                 * @access private
     83                 */
    7884                init: function() {
    7985                        var self = this,
    80                                 startPage,
    81                                 queryArray = {},
    82                                 queryString = window.location.search;
     86                                startPage;
    8387
    8488                        // We're using infinite scrolling, so hide all pagination.
    8589                        $('.pagination-links').hide();
    8690
    87                         // Parse GET query string
    88                         queryArray = this.parseQuery( queryString.substring( 1 ) );
     91                        // Get out early if we don't have the required arguments.
     92                        if ( ajaxurl === undefined ||
     93                                 list_args === undefined ||
     94                                 theme_list_args === undefined )
     95                                return;
    8996
    9097                        // Handle inputs
    9198                        this.nonce = $('#_ajax_fetch_list_nonce').val();
    92                         this.search = queryArray['s'];
    93                         this.features = queryArray['features'];
    94                         this.tab = queryArray['tab'];
    95                         this.type = queryArray['type'];
    9699
    97                         startPage = parseInt( queryArray['paged'], 10 );
    98                         if ( ! isNaN( startPage ) )
     100                        startPage = theme_list_args.paged;
     101                        if ( startPage !== undefined )
    99102                                this.nextPage = ( startPage + 1 );
    100103
    101104                        // Cache jQuery selectors
     
    104107                        this.$window = $(window);
    105108                        this.$document = $(document);
    106109
    107                         if ( $('.tablenav-pages').length )
     110                        /**
     111                         * If there are more pages to query, then start polling to track
     112                         * when user hits the bottom of the current page
     113                         */
     114                        if ( theme_list_args.total_pages !== undefined &&
     115                                 theme_list_args.total_pages >= this.nextPage )
    108116                                this.pollInterval =
    109117                                        setInterval( function() {
    110118                                                return self.poll();
    111119                                        }, this.scrollPollingDelay );
    112120                },
     121
     122                /**
     123                 * Checks to see if user has scrolled to bottom of page.
     124                 * If so, requests another page of content from self.ajax().
     125                 *
     126                 * @since 3.4
     127                 * @access private
     128                 */
    113129                poll: function() {
    114130                        var bottom = this.$document.scrollTop() + this.$window.innerHeight();
    115131
     
    119135
    120136                        this.ajax();
    121137                },
     138
     139                /**
     140                 * Applies results passed from this.ajax() to $outList
     141                 *
     142                 * @since 3.4
     143                 * @access private
     144                 *
     145                 * @param results Array with results from this.ajax() query.
     146                 */
    122147                process: function( results ) {
    123148                        if ( ( results === undefined ) ||
    124                                 ( results.rows.indexOf( 'no-items' ) != -1 ) ) {
     149                                 ( results.rows === undefined ) ||
     150                                 ( results.rows.indexOf( 'no-items' ) != -1 ) ) {
    125151                                clearInterval( this.pollInterval );
    126152                                return;
    127153                        }
    128154
    129                         var totalPages = parseInt( results.total_pages, 10 );
    130                         if ( this.nextPage > totalPages )
     155                        if ( this.nextPage > theme_list_args.total_pages )
    131156                                clearInterval( this.pollInterval );
    132157
    133                         if ( this.nextPage <= ( totalPages + 1 ) )
     158                        if ( this.nextPage <= ( theme_list_args.total_pages + 1 ) )
    134159                                this.$outList.append( results.rows );
    135160                },
     161
     162                /**
     163                 * Queries next page of themes
     164                 *
     165                 * @since 3.4
     166                 * @access private
     167                 */
    136168                ajax: function() {
    137169                        var self = this;
     170
    138171                        this.querying = true;
    139172
    140173                        var query = {
    141174                                action: 'fetch-list',
    142                                 tab: this.tab,
    143175                                paged: this.nextPage,
    144                                 s: this.search,
    145                                 type: this.type,
     176                                s: theme_list_args.search,
     177                                tab: theme_list_args.tab,
     178                                type: theme_list_args.type,
    146179                                _ajax_fetch_list_nonce: this.nonce,
    147                                 'features[]': this.features,
     180                                'features[]': theme_list_args.features,
    148181                                'list_args': list_args
    149182                        };
    150183
     
    159192                                .fail( function() {
    160193                                        self.$spinner.css( 'visibility', 'hidden' );
    161194                                        self.querying = false;
    162                                         setTimeout( function() { self.ajax(); }, self.failedRetryDelay )
     195                                        setTimeout( function() { self.ajax(); }, self.failedRetryDelay );
    163196                                });
    164                 },
    165                 parseQuery: function( query ) {
    166                         var params = {};
    167                         if ( ! query )
    168                                 return params;
    169 
    170                         var pairs = query.split( /[;&]/ );
    171                         for ( var i = 0; i < pairs.length; i++ ) {
    172                                 var keyVal = pairs[i].split( '=' );
    173 
    174                                 if ( ! keyVal || keyVal.length != 2 )
    175                                         continue;
    176 
    177                                 var key = unescape( keyVal[0] );
    178                                 var val = unescape( keyVal[1] );
    179                                 val = val.replace( /\+/g, ' ' );
    180                                 key = key.replace( /\[.*\]$/g, '' );
    181 
    182                                 if ( params[key] === undefined ) {
    183                                         params[key] = val;
    184                                 } else {
    185                                         var oldVal = params[key];
    186                                         if ( ! $.isArray( params[key] ) )
    187                                                 params[key] = new Array( oldVal, val );
    188                                         else
    189                                                 params[key].push( val );
    190                                 }
    191                         }
    192                         return params;
    193197                }
    194198        }
    195199
    196         $(document).ready( function( $ ) { ThemeScroller.init(); });
     200        $(document).ready( function($) {
     201                ThemeScroller.init();
     202        });
    197203
    198204})(jQuery);