Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Str/EmojiFormatter.php
<?php

namespace XF\Str;

use
JoyPixels\Client;
use
JoyPixels\Ruleset;

use function
array_key_exists, in_array, is_array;

class
EmojiFormatter
{
    const
UC_OUTPUT = 0;
    const
UC_MATCH = 1;
    const
UC_BASE = 2;

   
/**
     * @var Client
     */
   
protected $client;

    protected
$config = [];

    public function
__construct(array $config)
    {
       
$this->client = new Client($this->getRuleset());
       
$this->config = $this->setTypeSpecificDefaults($config);
    }

    public function
formatEmojiToImage($string)
    {
        if (
$this->config['style'] == 'native')
        {
            return
$string;
        }

       
$client = $this->client;

       
$string = preg_replace_callback('/' . $client->ignoredRegexp . '|' . $client->unicodeRegexp . '/u', function($match) use($client)
        {
            if (!
is_array($match) || !isset($match[0]) || empty($match[0]))
            {
                return
$match[0];
            }

           
$ruleset = $this->getRuleset();
           
$unicodeReplace = $ruleset->getUnicodeReplace();

           
$unicode = strtoupper($match[0]);

            if (
array_key_exists($unicode, $unicodeReplace))
            {
               
$shortname = $unicodeReplace[$unicode];
            }
            else
            {
                return
$match[0];
            }

            return
$this->getImageFromShortname($shortname);
        },  
$string);

        return
$string;
    }

    public function
formatShortnameToImage($string)
    {
       
$client = $this->client;

       
$string = preg_replace_callback('/' . $client->ignoredRegexp . '|(' . $client->shortcodeRegexp . ')/Si', function($match)
        {
            if (!
is_array($match) || !isset($match[1]) || empty($match[1]))
            {
                return
$match[0];
            }
            else
            {
               
$ruleset = $this->getRuleset();
               
$shortcodeReplace = $ruleset->getShortcodeReplace();

               
$shortname = $match[1];

                if (!isset(
$shortcodeReplace[$shortname]))
                {
                    return
$match[0];
                }

                return
$this->getImageFromShortname($shortname);
            }
        },
$string);

        return
$string;
    }

    public function
getImageFromShortname($shortname, $lazyLoad = false)
    {
       
$config = $this->config;
       
$alt = $this->formatShortnameToEmoji($shortname);

        if (
$config['style'] == 'native')
        {
            return
$alt;
        }

       
$ruleset = $this->getRuleset();
       
$shortcodeReplace = $ruleset->getShortcodeReplace();

        if (!isset(
$shortcodeReplace[$shortname]))
        {
            return
$alt;
        }

       
$filename = $shortcodeReplace[$shortname][$config['uc_filename']];
       
$filename = $config['filename_formatter']($filename);

       
$title = $this->getEmojiNameFromShortname($shortname) . '    ' . $shortname;

        if (
$lazyLoad)
        {
            return
'<span class="smilie smilie--emoji smilie--lazyLoad"'
               
. ' data-alt="' . htmlspecialchars($alt) . '" title="' . htmlspecialchars($title) . '"'
               
. ' data-src="' . htmlspecialchars($config['path'] . $filename) . '.png"'
               
. ' data-shortname="' . $shortname . '"></span>';
        }
        else
        {
            return
'<img class="smilie smilie--emoji" loading="lazy"'
           
. ' alt="' . htmlspecialchars($alt) . '" title="' . htmlspecialchars($title) . '"'
           
. ' src="' . htmlspecialchars($config['path'] . $filename) . '.png"'
           
. ' data-shortname="' . htmlspecialchars($shortname) . '"'
           
. ' />';
        }
    }

    public function
getEmojiNameFromShortname($shortname)
    {
        return \
XF::phrase('emoji.' . str_replace('-', '_', str_replace(':', '', strtolower(utf8_romanize(utf8_deaccent($shortname))))));
    }

    public function
formatShortnameToEmojiExceptions($string, array $exceptions = [], $native = true)
    {
       
$client = $this->client;

       
$exceptionsKeyed = array_fill_keys(array_map('strtolower', $exceptions), true);

       
$string = preg_replace_callback(
           
'/' . $client->ignoredRegexp . '|(\B:([-+\w]+):\B)/Siu',
            function(
$match) use($client, $native, $exceptionsKeyed)
            {
                if (!
is_array($match) || !isset($match[1]) || empty($match[1]))
                {
                    return
$match[0];
                }
                else
                {
                   
$ruleset = $this->getRuleset();
                   
$shortcodeReplace = $ruleset->getShortcodeReplace();

                   
$shortname = strtolower($match[1]);

                    if (isset(
$exceptionsKeyed[$shortname]))
                    {
                        return
$match[0];
                    }

                    if (!
array_key_exists($shortname, $shortcodeReplace))
                    {
                        return
$match[0];
                    }

                   
$unicode = $shortcodeReplace[$shortname][0];
                   
$unicode = $client->convert($unicode);

                    if (
$native)
                    {
                        return
html_entity_decode($unicode);
                    }
                    else
                    {
                        return
$unicode;
                    }
                }
            },
           
$string
       
);

        return
$string;
    }

    public function
formatShortnameToEmoji($string, $native = true)
    {
        return
$this->formatShortnameToEmojiExceptions($string, [], $native);
    }

    public function
formatEmojiToShortname($string)
    {
        return
$this->client->toShort($string);
    }

   
/**
     * @return Client
     */
   
public function getClient()
    {
        return
$this->client;
    }

   
/**
     * @return Ruleset
     */
   
public function getRuleset()
    {
        return new
Ruleset();
    }

    protected function
setTypeSpecificDefaults($config)
    {
        if (
$config['style'] == 'native')
        {
            return
$config;
        }

       
$useCdn = ($config['source'] == 'cdn');

        if (
$config['style'] == 'emojione')
        {
           
$config['path'] = $useCdn ? 'https://cdn.jsdelivr.net/joypixels/assets/6.6/png/unicode/64/' : $config['path'];
           
$config['uc_filename'] = self::UC_MATCH;
           
$config['filename_formatter'] = function($filename) { return $filename; };
        }
        else if (
$config['style'] == 'twemoji')
        {
           
$config['path'] = $useCdn ? 'https://twemoji.maxcdn.com/2/72x72/' : $config['path'];
           
$config['uc_filename'] = self::UC_OUTPUT;
           
$config['filename_formatter'] = function($filename)
            {
               
// Twemoji strips the leading zeros.
               
if (strpos($filename, '00') === 0)
                {
                   
$filename = preg_replace('/^(00)/', '', $filename);
                }

               
// Some Twemoji symbols don't include the fe0f 'variant form' indicator
               
if (strpos($filename, '-fe0f-') !== false)
                {
                   
$filename = preg_replace('/^(\w{2})(?:-fe0f-)(.*)$/', '$1-$2', $filename);
                }

               
/**
                 * Some Twemoji file names are different to what we would expect
                 * so handle those replacements manually based on a known list
                 */
               
$filename = $this->getTwemojiReplacement($filename);

                return
$filename;
            };
        }

        return
$config;
    }

    protected function
getTwemojiReplacement(string $filename): string
   
{
       
$replacements = [
           
'263a-fe0f', '2639-fe0f', '2620-fe0f', '270c-fe0f', '261d-fe0f', '270d-fe0f', '1f441-fe0f', '1f5e3-fe0f', '1f574-fe0f', '26d1-fe0f', '1f576-fe0f', '1f577-fe0f', '1f578-fe0f', '1f54a-fe0f', '1f43f-fe0f', '2618-fe0f', '2604-fe0f', '1f32a-fe0f', '2600-fe0f', '1f324-fe0f', '1f325-fe0f', '2601-fe0f', '1f326-fe0f', '1f327-fe0f', '26c8-fe0f', '1f329-fe0f', '1f328-fe0f', '2744-fe0f', '2603-fe0f', '1f32c-fe0f', '2602-fe0f', '1f32b-fe0f', '1f336-fe0f', '1f37d-fe0f', '26f8-fe0f', '26f7-fe0f', '1f396-fe0f', '1f3f5-fe0f', '1f397-fe0f', '1f39f-fe0f', '265f-fe0f', '1f3ce-fe0f', '1f3cd-fe0f', '2708-fe0f', '1f6e9-fe0f', '1f6f0-fe0f', '1f6e5-fe0f', '1f6f3-fe0f', '26f4-fe0f', '1f5fa-fe0f', '1f3df-fe0f', '26f1-fe0f', '1f3d6-fe0f', '1f3dd-fe0f', '1f3dc-fe0f', '26f0-fe0f', '1f3d4-fe0f', '1f3d5-fe0f', '1f3d8-fe0f', '1f3da-fe0f', '1f3d7-fe0f', '1f3db-fe0f', '26e9-fe0f', '1f6e4-fe0f', '1f6e3-fe0f', '1f3de-fe0f', '1f3d9-fe0f', '2328-fe0f', '1f5a5-fe0f', '1f5a8-fe0f', '1f5b1-fe0f', '1f5b2-fe0f', '1f579-fe0f', '1f5dc-fe0f', '1f4fd-fe0f', '1f39e-fe0f', '260e-fe0f', '1f399-fe0f', '1f39a-fe0f', '1f39b-fe0f', '23f1-fe0f', '23f2-fe0f', '1f570-fe0f', '1f56f-fe0f', '1f6e2-fe0f', '2696-fe0f', '2692-fe0f', '1f6e0-fe0f', '26cf-fe0f', '2699-fe0f', '26d3-fe0f', '1f5e1-fe0f', '2694-fe0f', '1f6e1-fe0f', '26b0-fe0f', '26b1-fe0f', '2697-fe0f', '1f573-fe0f', '1f321-fe0f', '1f6ce-fe0f', '1f5dd-fe0f', '1f6cb-fe0f', '1f6cf-fe0f', '1f5bc-fe0f', '1f6cd-fe0f', '2709-fe0f', '1f3f7-fe0f', '1f5d2-fe0f', '1f5d3-fe0f', '1f5d1-fe0f', '1f5c3-fe0f', '1f5f3-fe0f', '1f5c4-fe0f', '1f5c2-fe0f', '1f5de-fe0f', '1f587-fe0f', '2702-fe0f', '1f58a-fe0f', '1f58b-fe0f', '2712-fe0f', '1f58c-fe0f', '1f58d-fe0f', '270f-fe0f', '2764-fe0f', '2763-fe0f', '262e-fe0f', '271d-fe0f', '262a-fe0f', '1f549-fe0f', '2638-fe0f', '2721-fe0f', '262f-fe0f', '2626-fe0f', '269b-fe0f', '2622-fe0f', '2623-fe0f', '1f237-fe0f', '2734-fe0f', '3299-fe0f', '3297-fe0f', '1f170-fe0f', '1f171-fe0f', '1f17e-fe0f', '2668-fe0f', '203c-fe0f', '2049-fe0f', '303d-fe0f', '26a0-fe0f', '269c-fe0f', '267b-fe0f', '2747-fe0f', '2733-fe0f', '24c2-fe0f', '1f17f-fe0f', '1f202-fe0f', '2139-fe0f', '23cf-fe0f', '25b6-fe0f', '23f8-fe0f', '23ef-fe0f', '23f9-fe0f', '23fa-fe0f', '23ed-fe0f', '23ee-fe0f', '25c0-fe0f', '27a1-fe0f', '2b05-fe0f', '2b06-fe0f', '2b07-fe0f', '2197-fe0f', '2198-fe0f', '2199-fe0f', '2196-fe0f', '2195-fe0f', '2194-fe0f', '21aa-fe0f', '21a9-fe0f', '2934-fe0f', '2935-fe0f', '2716-fe0f', '267e-fe0f', '2122-fe0f', 'a9-fe0f', 'ae-fe0f', '3030-fe0f', '2714-fe0f', '2611-fe0f', '25aa-fe0f', '25ab-fe0f', '25fc-fe0f', '25fb-fe0f', '1f5e8-fe0f', '1f441-fe0f-200d-1f5e8-fe0f', '1f5ef-fe0f', '2660-fe0f', '2663-fe0f', '2665-fe0f', '2666-fe0f', '2640-fe0f', '2642-fe0f', '2695-fe0f', '1f3f3-fe0f'
       
];

        if (
in_array($filename, $replacements))
        {
            return
str_replace('-fe0f', '', $filename);
        }
        else
        {
            return
$filename;
        }
    }
}