AutocompletePostListLoader.php
2 months ago
DateTime.php
1 year ago
Emoji.php
2 months ago
Functions.php
1 week ago
Notice.php
3 years ago
Posts.php
3 years ago
Readme.php
3 years ago
index.php
3 years ago
Emoji.php
87 lines
| 1 | <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing |
| 2 | |
| 3 | namespace MailPoet\WP; |
| 4 | |
| 5 | if (!defined('ABSPATH')) exit; |
| 6 | |
| 7 | |
| 8 | use MailPoet\DI\ContainerWrapper; |
| 9 | use MailPoet\Form\FormsRepository; |
| 10 | use MailPoet\Newsletter\Sending\SendingQueuesRepository; |
| 11 | use MailPoet\WP\Functions as WPFunctions; |
| 12 | |
| 13 | class Emoji { |
| 14 | /** @var WPFunctions */ |
| 15 | private $wp; |
| 16 | |
| 17 | public function __construct( |
| 18 | ?WPFunctions $wp = null |
| 19 | ) { |
| 20 | if ($wp === null) { |
| 21 | $wp = new WPFunctions(); |
| 22 | } |
| 23 | $this->wp = $wp; |
| 24 | } |
| 25 | |
| 26 | public function encodeEmojisInBody($newsletterRenderedBody) { |
| 27 | if (is_array($newsletterRenderedBody)) { |
| 28 | return array_map([$this, 'encodeRenderedBodyForUTF8Column'], $newsletterRenderedBody); |
| 29 | } |
| 30 | return $this->encodeRenderedBodyForUTF8Column($newsletterRenderedBody); |
| 31 | } |
| 32 | |
| 33 | public function decodeEmojisInBody($newsletterRenderedBody) { |
| 34 | if (is_array($newsletterRenderedBody)) { |
| 35 | return array_map([$this, 'decodeEntities'], $newsletterRenderedBody); |
| 36 | } |
| 37 | return $this->decodeEntities($newsletterRenderedBody); |
| 38 | } |
| 39 | |
| 40 | public function sanitizeEmojisInFormBody(array $body): array { |
| 41 | $formsTableName = ContainerWrapper::getInstance()->get(FormsRepository::class)->getTableName(); |
| 42 | $bodyJson = json_encode($body, JSON_UNESCAPED_UNICODE); |
| 43 | $fixedJson = $this->encodeForUTF8Column($formsTableName, 'body', $bodyJson); |
| 44 | $decoded = json_decode($fixedJson, true); |
| 45 | return is_array($decoded) ? $decoded : $body; |
| 46 | } |
| 47 | |
| 48 | private function encodeRenderedBodyForUTF8Column($value) { |
| 49 | $sendingQueuesTableName = ContainerWrapper::getInstance()->get(SendingQueuesRepository::class)->getTableName(); |
| 50 | return $this->encodeForUTF8Column( |
| 51 | $sendingQueuesTableName, |
| 52 | 'newsletter_rendered_body', |
| 53 | $value |
| 54 | ); |
| 55 | } |
| 56 | |
| 57 | public function encodeForUTF8Column($table, $field, $value) { |
| 58 | global $wpdb; |
| 59 | $charset = $wpdb->get_col_charset($table, $field); |
| 60 | // utf8 doesn't support emojis, so we need to encode them |
| 61 | // utf8 was an alias for utf8mb3, but it was dropped in MySQL 8.0.28 so we need to check both |
| 62 | if ($charset === 'utf8' || $charset === 'utf8mb3') { |
| 63 | $value = $this->wp->wpEncodeEmoji($value); |
| 64 | } |
| 65 | return $value; |
| 66 | } |
| 67 | |
| 68 | public function decodeEntities($content) { |
| 69 | // Based on WPFunctions::get()->wpStaticizeEmoji() |
| 70 | |
| 71 | // Loosely match the Emoji Unicode range. |
| 72 | $regex = '/(&#x[2-3][0-9a-f]{3};|[1-6][0-9a-f]{2};)/'; |
| 73 | |
| 74 | $matches = []; |
| 75 | if (preg_match_all($regex, $content, $matches)) { |
| 76 | if (!empty($matches[1])) { |
| 77 | foreach ($matches[1] as $emoji) { |
| 78 | $entity = html_entity_decode($emoji, ENT_COMPAT, 'UTF-8'); |
| 79 | $content = str_replace($emoji, $entity, $content); |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | return $content; |
| 85 | } |
| 86 | } |
| 87 |