WordPress.org

Make WordPress Core

Ticket #21212: 21212-emoji.diff

File 21212-emoji.diff, 3.3 KB (added by pento, 5 years ago)
  • src/wp-admin/includes/post.php

     
    325325
    326326                foreach( $fields as $field ) {
    327327                        if ( isset( $post_data[ $field ] ) ) {
     328                                $charset = $wpdb->get_col_charset( $wpdb->posts, $field );
     329                                if ( 'utf8' === $charset ) {
     330                                        $post_data[ $field ] = wp_encode_emoji( $post_data[ $field ] );
     331                                }
    328332                                $post_data[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->posts, $field, $post_data[ $field ] );
    329333                        }
    330334                }
  • src/wp-includes/formatting.php

     
    33183318
    33193319                case 'blogdescription':
    33203320                case 'blogname':
     3321                        $charset = $wpdb->get_col_charset( $wpdb->options, 'option_value' );
     3322                        if ( 'utf8' === $charset ) {
     3323                                $value = wp_encode_emoji( $value );
     3324                        }
    33213325                        $value = $wpdb->strip_invalid_text_for_column( $wpdb->options, 'option_value', $value );
    33223326                        $value = wp_kses_post( $value );
    33233327                        $value = esc_html( $value );
     
    40154019
    40164020        return $spaces;
    40174021}
     4022
     4023/**
     4024 * Convert any 4 byte emoji in a string to their equivalent HTML entitiy.
     4025 *
     4026 * This allows us to store emoji in a DB using the utf8 character set.
     4027 *
     4028 * @since 4.2.0
     4029 * @param  string $content The content to encode
     4030 * @return string The encoded content
     4031 */
     4032function wp_encode_emoji( $content ) {
     4033        if ( function_exists( 'mb_convert_encoding' ) ) {
     4034                $regex = '/(
     4035                          \x23\xE2\x83\xA3               # Digits
     4036                          [\x30-\x39]\xE2\x83\xA3
     4037                        | \xF0\x9F[\x85-\x88][\xB0-\xBF] # Enclosed characters
     4038                        | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc
     4039                        | \xF0\x9F\x98[\x80-\xBF]        # Smilies
     4040                        | \xF0\x9F\x99[\x80-\x8F]
     4041                        | \xF0\x9F\x9A[\x80-\xBF]        # Transport and map symbols
     4042                        | \xF0\x9F\x99[\x80-\x85]
     4043                )/x';
     4044                $matches = array();
     4045                if ( preg_match_all( $regex, $content, $matches ) ) {
     4046                        if ( ! empty( $matches[1] ) ) {
     4047                                foreach( $matches[1] as $emoji ) {
     4048                                        $unpacked = unpack( 'H*', mb_convert_encoding( $emoji, 'UTF-32', 'UTF-8' ) );
     4049                                        if ( isset( $unpacked[1] ) ) {
     4050                                                $entity = '&#x' . trim( $unpacked[1], '0' ) . ';';
     4051                                                $content = str_replace( $emoji, $entity, $content );
     4052                                        }
     4053                                }
     4054                        }
     4055                }
     4056        }
     4057
     4058        return $content;
     4059}
     4060 No newline at end of file
  • tests/phpunit/tests/formatting/Emoji.php

     
     1<?php
     2
     3/**
     4 * @group formatting
     5 * @group emoji
     6 */
     7class Tests_Formatting_Emoji extends WP_UnitTestCase {
     8        public function test_emoji_encoding() {
     9                $content = "foo\xf0\x9f\x98\x89bar";
     10                $expected = "foo&#x1f609;bar";
     11                $encoded = wp_encode_emoji( $content );
     12                $this->assertEquals( $expected, $encoded );
     13        }
     14
     15        public function test_non_emoji_encoding() {
     16                $content = "foo\xe5\x85\xb1bar";
     17                $encoded = wp_encode_emoji( $content );
     18                $this->assertEquals( $content, $encoded );
     19        }
     20}