WordPress.org

Make WordPress Core

Ticket #14691: 14691.diff

File 14691.diff, 14.5 KB (added by mdawaffe, 8 years ago)
  • wp-includes/compat.php

     
    168168        }
    169169        return $parts;
    170170}
     171
     172// Added in PHP 5.3
     173if ( !function_exists( 'str_getcsv' ) ) {
     174        class _CSV_Read_StreamWrapper {
     175                var $data;
     176                var $pos;
     177                function stream_open( $path ) {
     178                        $this->data = substr( $path, 10 );
     179                        $this->pos = 0;
     180                        return true;
     181                }
     182                function stream_read( $count ) {
     183                        $r = substr( $this->data, $this->pos, $count );
     184                        $this->pos += strlen( $r );
     185                        return $r;
     186                }
     187                function stream_eof() {
     188                        return $this->pos >= strlen( $this->data );
     189                }
     190                function stream_tell() {
     191                        return $this->pos;
     192                }
     193        }
     194
     195        function str_getcsv( $input, $delimiter = ',', $enclosure = '"' ) {
     196                static $registered = false;
     197                if ( !$registered ) {
     198                        stream_wrapper_register( 'str.csv', '_CSV_Read_StreamWrapper' );
     199                        $registered = true;
     200                }
     201
     202                if ( !$f = fopen( 'str.csv://' . $input, 'r' ) )
     203                        return;
     204
     205                // Only return first line
     206                $r = fgetcsv( $f, strlen( $input ), $delimiter, $enclosure );
     207                fclose( $f );
     208                return $r;
     209        }
     210}
     211
     212// May be added in PHP-Future
     213if ( !function_exists( 'str_putcsv' ) ) {
     214        function str_putcsv( $fields, $delimiter = ',', $enclosure = '"' ) {
     215                static $which = false;
     216                if ( !$which )
     217                        $which = function_exists( 'fputcsv' ) ? 1 : 2;
     218
     219                switch ( $which ) {
     220                case 1 :
     221                        // This is faster than php://memory
     222                        ob_start();
     223                        $f = fopen( 'php://output', 'w' );
     224                                fputcsv( $f, $fields, $delimiter, $enclosure );
     225                        fclose( $f );
     226                        return trim( ob_get_clean() );
     227                case 2 :
     228                        $_d = preg_quote( $delimiter, '/' );
     229                        $_e = preg_quote( $enclosure, '/' );
     230                        $ee = "{$enclosure}{$enclosure}";
     231                        foreach ( array_keys( $fields ) as $i ) {
     232                                // May quote elements that don't need it.  Who cares?
     233                                if ( !preg_match( "/[\s{$_d}{$_e}]/", $fields[$i] ) )
     234                                        continue;
     235                                $fields[$i] = $enclosure . str_replace( $enclosure, $ee, $fields[$i] ) . $enclosure;
     236                        }
     237                        return join( $delimiter, $fields );
     238                }
     239        }
     240}
  • wp-includes/post.php

     
    26392639        if ( empty($tags) )
    26402640                $tags = array();
    26412641
    2642         $tags = is_array($tags) ? $tags : explode( ',', trim($tags, " \n\t\r\0\x0B,") );
     2642        if ( !is_array( $tags ) ) {
     2643                $tags = stripslashes( trim( $tags, " \n\t\r\0\x0B," ) );
     2644                $tags = array_map( 'addslashes', str_getcsv( $tags ) );
     2645        }
    26432646
    26442647        // Hierarchical taxonomies must always pass IDs rather than names so that children with the same
    26452648        // names but different parents aren't confused.
  • wp-includes/js/csv.dev.js

     
     1// http://www.bennadel.com/blog/1504-Ask-Ben-Parsing-CSV-Strings-With-Javascript-Exec-Regular-Expression-Command.htm
     2//
     3// This will parse a delimited string into an array of
     4// arrays. The default delimiter is the comma, but this
     5// can be overriden in the second argument.
     6function CSVToArray( strData, strDelimiter ){
     7        // Check to see if the delimiter is defined. If not,
     8        // then default to comma.
     9        strDelimiter = (strDelimiter || ",");
     10 
     11        // Create a regular expression to parse the CSV values.
     12        var objPattern = new RegExp(
     13                (
     14                        // WordPress.org
     15                        // was: "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
     16
     17                        // Delimiters.
     18                        "\\s*(\\" + strDelimiter + "|\\r?\\n|\\r|^)\\s*" +
     19 
     20                        // Quoted fields.
     21                        "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
     22 
     23                        // Standard fields.
     24                        "([^\"\\" + strDelimiter + "\\r\\n]*))"
     25                ),
     26                "gi"
     27                );
     28 
     29 
     30        // Create an array to hold our data. Give the array
     31        // a default empty first row.
     32        var arrData = [[]];
     33 
     34        // Create an array to hold our individual pattern
     35        // matching groups.
     36        var arrMatches = null;
     37
     38        // WordPress.org
     39        if ( !strData )
     40                return arrData;
     41 
     42        // Keep looping over the regular expression matches
     43        // until we can no longer find a match.
     44        while (arrMatches = objPattern.exec( strData )){
     45 
     46                // Get the delimiter that was found.
     47                var strMatchedDelimiter = arrMatches[ 1 ];
     48 
     49                // Check to see if the given delimiter has a length
     50                // (is not the start of string) and if it matches
     51                // field delimiter. If id does not, then we know
     52                // that this delimiter is a row delimiter.
     53                if (
     54                        strMatchedDelimiter.length &&
     55                        (strMatchedDelimiter != strDelimiter)
     56                        ){
     57 
     58                        // Since we have reached a new row of data,
     59                        // add an empty row to our data array.
     60                        arrData.push( [] );
     61 
     62                }
     63 
     64 
     65                // Now that we have our delimiter out of the way,
     66                // let's check to see which kind of value we
     67                // captured (quoted or unquoted).
     68                if (arrMatches[ 2 ]){
     69 
     70                        // We found a quoted value. When we capture
     71                        // this value, unescape any double quotes.
     72                        var strMatchedValue = arrMatches[ 2 ].replace(
     73                                new RegExp( "\"\"", "g" ),
     74                                "\""
     75                                );
     76 
     77                } else {
     78 
     79                        // We found a non-quoted value.
     80                        var strMatchedValue = arrMatches[ 3 ];
     81 
     82                }
     83 
     84 
     85                // Now that we have our value string, let's add
     86                // it to the data array.
     87                arrData[ arrData.length - 1 ].push( strMatchedValue );
     88        }
     89 
     90        // Return the parsed data.
     91        return( arrData );
     92}
     93
     94// WordPress.org
     95function ArrayToCSV( arrFields, strDelimiter ) {
     96        var quoteReg = new RegExp( "[^\"\\" + strDelimiter + "\\r\\n]" );
     97        for ( var i in arrFields ) {
     98                if ( !quoteReg.test( arrFields[i] ) ) {
     99                        continue;
     100                }
     101
     102                arrFields[i] = '"' + arrFields[i].replace( '"', '""' ) + '"';
     103        }
     104
     105        return arrFields.join( strDelimiter );
     106}
  • wp-includes/formatting.php

     
    28412841
    28422842}
    28432843
    2844 ?>
     2844/**
     2845 * Acts like str_putcsv (which takes an array of strings and outputs a CSV line) except
     2846 * the delimiter may be a single character surrounded by arbitrary whitespace.
     2847 *
     2848 * @link http://php.net/fputcsv
     2849 *
     2850 * @param array $fields array( $string_1, $string_2, ... )
     2851 * @param string $delimiter Any single character or any single character with any amount of leading and trailing whitespace.
     2852 * @param string $enclosure Any single character
     2853 *
     2854 * @since 3.1.0
     2855 */
     2856function wp_str_putcsv( $fields, $delimiter = ',', $enclosure = '"' ) {
     2857        $trim_delim = trim( $delimiter );
     2858
     2859        if ( 1 == strlen( $delimiter ) || $trim_delim == $delimiter )
     2860                return str_putcsv( $fields, $delimiter, $enclosure );
     2861
     2862        if ( !$trim_delim )
     2863                $trim_delim = ' ';
     2864
     2865        $r = array();
     2866        foreach ( $fields as $field )
     2867                $r[] = str_putcsv( array( $field ), $trim_delim, $enclosure );
     2868        return join( $delimiter, $r );
     2869}
  • wp-includes/script-loader.php

     
    226226        $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.1' );
    227227        $scripts->add_data( 'imgareaselect', 'group', 1 );
    228228
     229        $scripts->add( 'csv', "/wp-includes/js/csv$suffix.js", false, '20100823' );
     230
    229231        if ( is_admin() ) {
    230232                $scripts->add( 'ajaxcat', "/wp-admin/js/cat$suffix.js", array( 'wp-lists' ), '20090102' );
    231233                $scripts->add_data( 'ajaxcat', 'group', 1 );
     
    278280                $scripts->add( 'postbox', "/wp-admin/js/postbox$suffix.js", array('jquery-ui-sortable'), '20091012' );
    279281                $scripts->add_data( 'postbox', 'group', 1 );
    280282
    281                 $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array('suggest', 'wp-lists', 'postbox'), '20100526' );
     283                $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array('suggest', 'wp-lists', 'postbox', 'csv' ), '20100823' );
    282284                $scripts->add_data( 'post', 'group', 1 );
    283285                $scripts->localize( 'post', 'postL10n', array(
    284286                        'tagsUsed' =>  __('Tags used on this post:'),
  • wp-admin/includes/taxonomy.php

     
    194194 *
    195195 * @since unknown
    196196 *
    197  * @param unknown_type $post_id
    198  * @return unknown
     197 * @param int $post_id
     198 * @param string $taxonomy
     199 * @param string $delimiter @since 3.1.0
     200 *
     201 * @return string CSV line of term names
    199202 */
    200 function get_tags_to_edit( $post_id, $taxonomy = 'post_tag' ) {
    201         return get_terms_to_edit( $post_id, $taxonomy);
     203function get_tags_to_edit( $post_id, $taxonomy = 'post_tag', $delimiter = ',' ) {
     204        return get_terms_to_edit( $post_id, $taxonomy, $delimiter = ',' );
    202205}
    203206
    204207/**
     
    206209 *
    207210 * @since unknown
    208211 *
    209  * @param unknown_type $post_id
    210  * @return unknown
     212 * @param int $post_id
     213 * @param string $taxonomy
     214 * @param string $delimiter @since 3.1.0
     215 *
     216 * @return string CSV line of term names
    211217 */
    212 function get_terms_to_edit( $post_id, $taxonomy = 'post_tag' ) {
     218function get_terms_to_edit( $post_id, $taxonomy = 'post_tag', $delimiter = ',' ) {
    213219        $post_id = (int) $post_id;
    214220        if ( !$post_id )
    215221                return false;
     
    224230
    225231        foreach ( $tags as $tag )
    226232                $tag_names[] = $tag->name;
    227         $tags_to_edit = join( ',', $tag_names );
     233        $tags_to_edit = wp_str_putcsv( $tag_names, $delimiter );
    228234        $tags_to_edit = esc_attr( $tags_to_edit );
    229235        $tags_to_edit = apply_filters( 'terms_to_edit', $tags_to_edit, $taxonomy );
    230236
  • wp-admin/includes/post.php

     
    275275                        if ( is_taxonomy_hierarchical( $tax_name ) )
    276276                                $tax_input[$tax_name] = array_map( 'absint', $terms );
    277277                        else {
    278                                 $tax_input[$tax_name] = preg_replace( '/\s*,\s*/', ',', rtrim( trim($terms), ' ,' ) );
    279                                 $tax_input[$tax_name] = explode(',', $tax_input[$tax_name]);
     278                                $tax_input[$tax_name] = str_getcsv( rtrim( trim($terms), ' ,' ) );
    280279                        }
    281280                }
    282281        }
     
    12961295                $_POST['post_category'] = explode(",", $_POST['catslist']);
    12971296
    12981297        if ( isset($_POST['tags_input']) )
    1299                 $_POST['tags_input'] = explode(",", $_POST['tags_input']);
     1298                $_POST['tags_input'] = array_map( 'addslashes', str_getcsv( stripslashes( $_POST['tags_input'] ) ) );
    13001299
    13011300        if ( $_POST['post_type'] == 'page' || empty($_POST['post_category']) )
    13021301                unset($_POST['post_category']);
  • wp-admin/includes/dashboard.php

     
    452452
    453453                <h4><label for="tags-input"><?php _e('Tags') ?></label></h4>
    454454                <div class="input-text-wrap">
    455                         <input type="text" name="tags_input" id="tags-input" tabindex="3" value="<?php echo get_tags_to_edit( $post->ID ); ?>" />
     455                        <input type="text" name="tags_input" id="tags-input" tabindex="3" value="<?php echo get_terms_to_edit( $post->ID, 'post_tag', ', ' ); ?>" />
    456456                </div>
    457457
    458458                <p class="submit">
  • wp-admin/includes/meta-boxes.php

     
    256256        <div class="jaxtag">
    257257        <div class="nojs-tags hide-if-js">
    258258        <p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
    259         <textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php echo $disabled; ?>><?php echo esc_attr(get_terms_to_edit( $post->ID, $tax_name )); ?></textarea></div>
     259        <textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php echo $disabled; ?>><?php echo esc_html( get_terms_to_edit( $post->ID, $tax_name, ', ' ) ); ?></textarea></div>
    260260        <?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
    261261        <div class="ajaxtag hide-if-no-js">
    262262                <label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
  • wp-admin/includes/template.php

     
    266266                if ( $taxonomy->hierarchical && $taxonomy->show_ui )
    267267                                echo '<div class="post_category" id="'.$taxonomy_name.'_'.$post->ID.'">' . implode( ',', wp_get_object_terms( $post->ID, $taxonomy_name, array('fields'=>'ids')) ) . '</div>';
    268268                elseif ( $taxonomy->show_ui )
    269                         echo '<div class="tags_input" id="'.$taxonomy_name.'_'.$post->ID.'">' . esc_html( str_replace( ',', ', ', get_terms_to_edit($post->ID, $taxonomy_name) ) ) . '</div>';
     269                        echo '<div class="tags_input" id="'.$taxonomy_name.'_'.$post->ID.'">' . esc_html( get_terms_to_edit( $post->ID, $taxonomy_name, ', ' ) ) . '</div>';
    270270        }
    271271
    272272        if ( !$post_type_object->hierarchical )
  • wp-admin/js/post.dev.js

     
    1515
    1616tagBox = {
    1717        clean : function(tags) {
    18                 return tags.replace(/\s*,\s*/g, ',').replace(/,+/g, ',').replace(/[,\s]+$/, '').replace(/^[,\s]+/, '');
     18                if ( jQuery.isArray( tags ) ) {
     19                        arrTags = tags;
     20                } else {
     21                        arrTags = CSVToArray( tags )[0];
     22                }
     23
     24                return ArrayToCSV( array_unique_noempty( arrTags ) );
    1925        },
    2026
    2127        parseTags : function(el) {
    22                 var id = el.id, num = id.split('-check-num-')[1], taxbox = $(el).closest('.tagsdiv'), thetags = taxbox.find('.the-tags'), current_tags = thetags.val().split(','), new_tags = [];
     28                var id = el.id, num = id.split('-check-num-')[1], taxbox = $(el).closest('.tagsdiv'), thetags = taxbox.find('.the-tags'), current_tags = CSVToArray( thetags.val() )[0], new_tags = [];
    2329                delete current_tags[num];
    2430
    2531                $.each( current_tags, function(key, val) {
     
    2935                        }
    3036                });
    3137
    32                 thetags.val( this.clean( new_tags.join(',') ) );
     38                thetags.val( this.clean( new_tags ) );
    3339
    3440                this.quickClicks(taxbox);
    3541                return false;
     
    4349
    4450                var disabled = thetags.attr('disabled');
    4551
    46                 current_tags = thetags.val().split(',');
     52                current_tags = CSVToArray( thetags.val() )[0];
    4753                tagchecklist.empty();
    4854
    4955                $.each( current_tags, function( key, val ) {
     
    7278                newtags = tagsval ? tagsval + ',' + text : text;
    7379
    7480                newtags = this.clean( newtags );
    75                 newtags = array_unique_noempty( newtags.split(',') ).join(',');
    7681                tags.val(newtags);
    7782                this.quickClicks(el);
    7883