WordPress.org

Make WordPress Core

Ticket #19815: 19815.11.2.diff

File 19815.11.2.diff, 10.1 KB (added by mikeschroder, 6 years ago)

Refresh due to nacin's suggestions and updates

  • 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_terms = array();
     31                $search_string = '';
     32                if ( ! empty( $_REQUEST['s'] ) ){
     33                        $search_string = strtolower( stripslashes( $_REQUEST['s'] ) );
     34                        $search_terms = array_unique( array_filter( array_map( 'trim', explode( ',', $search_string ) ) ) );
     35                }
     36
     37                if ( ! empty( $_REQUEST['features'] ) )
     38                        $this->features = $_REQUEST['features'];
     39
    2940                $paged = $this->get_pagenum();
    3041
    3142                $per_page = 36;
     
    5566                switch ( $tab ) {
    5667                        case 'search':
    5768                                $type = isset( $_REQUEST['type'] ) ? stripslashes( $_REQUEST['type'] ) : '';
    58                                 $term = isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '';
    59 
    6069                                switch ( $type ) {
    6170                                        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;
     71                                                $args['tag'] = array_map( 'sanitize_title_with_dashes', $search_terms );
    6672                                                break;
    6773                                        case 'term':
    68                                                 $args['search'] = $term;
     74                                                $args['search'] = $search_string;
    6975                                                break;
    7076                                        case 'author':
    71                                                 $args['author'] = $term;
     77                                                $args['author'] = $search_string;
    7278                                                break;
    7379                                }
    7480
    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 );
     81                                if ( ! empty( $this->features ) ) {
     82                                        $args['tag'] = $this->features;
     83                                        $_REQUEST['s'] = implode( ',', $this->features );
    8184                                        $_REQUEST['type'] = 'tag';
    8285                                }
    8386
     
    9598                                $args = false;
    9699                }
    97100
    98                 if ( !$args )
     101                if ( ! $args )
    99102                        return;
    100103
    101104                $api = themes_api( 'query_themes', $args );
     
    170173                                ?></div>
    171174                <?php } // end foreach $theme_names
    172175        }
     176
     177        /**
     178         * Send required variables to JavaScript land
     179         *
     180         * @since 3.4
     181         * @access private
     182         *
     183         * @uses $tab Global; current tab within Themes->Install screen
     184         * @uses $type Global; type of search.
     185         * @uses $this->features Array of all feature search terms.
     186         * @uses get_pagenum()
     187         * @uses _pagination_args['total_pages']
     188         */
     189        function _js_vars() {
     190                global $tab, $type;
     191                $search_string = isset( $_REQUEST['s'] ) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
     192
     193                $total_pages = 0;
     194                if ( ! empty( $this->_pagination_args['total_pages'] ) )
     195                        $total_pages = $this->_pagination_args['total_pages'];
     196
     197                $args = array(
     198                        'search' => $search_string,
     199                        'features' => $this->features,
     200                        'paged' => $this->get_pagenum(),
     201                        'total_pages' => $total_pages,
     202                        'tab' => $tab,
     203                        'type' => $type,
     204                );
     205
     206                printf( "<script type='text/javascript'>theme_list_args = %s;</script>\n", json_encode( $args ) );
     207                parent::_js_vars();
     208        }
    173209}
  • wp-admin/includes/class-wp-themes-list-table.php

     
    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() {
     
    202202
    203203                return true;
    204204        }
     205
     206        /**
     207         * Send required variables to JavaScript land
     208         *
     209         * @since 3.4
     210         * @access private
     211         *
     212         * @uses $this->features Array of all feature search terms.
     213         * @uses get_pagenum()
     214         * @uses _pagination_args['total_pages']
     215         */
     216         function _js_vars() {
     217                $search_string = isset( $_REQUEST['s'] ) ? esc_attr( stripslashes( $_REQUEST['s'] ) ) : '';
     218
     219                $total_pages = 1;
     220                if ( ! empty( $this->_pagination_args['total_pages'] ) )
     221                        $total_pages = $this->_pagination_args['total_pages'];
     222
     223                $args = array(
     224                        'search' => $search_string,
     225                        'features' => $this->features,
     226                        'paged' => $this->get_pagenum(),
     227                        'total_pages' => $total_pages,
     228                );
     229
     230                printf( "<script type='text/javascript'>theme_list_args = %s;</script>\n", json_encode( $args ) );
     231                parent::_js_vars();
     232        }
    205233}
  • 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);