add emoji-detector

This commit is contained in:
Mike Macgirvin 2020-02-04 09:58:32 +11:00
parent 39f971609a
commit e878414816
16 changed files with 456 additions and 25 deletions

View file

@ -54,7 +54,8 @@
"league/oauth2-instagram": "^2.0",
"league/oauth2-linkedin": "^5.1",
"forkawesome/fork-awesome": "^1.1",
"svg-edit/svgedit": "^5.0"
"svg-edit/svgedit": "^5.0",
"p3k/emoji-detector": "^0.2.1"
},
"require-dev" : {
"phpunit/phpunit" : "@stable",

81
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "dbdfead079aad63bc11a08ddc672f623",
"content-hash": "1777c61a20a9b380c9f63f037d002248",
"packages": [
{
"name": "blueimp/jquery-file-upload",
@ -1381,6 +1381,47 @@
],
"time": "2019-12-02T02:32:27+00:00"
},
{
"name": "p3k/emoji-detector",
"version": "0.2.1",
"source": {
"type": "git",
"url": "https://github.com/aaronpk/emoji-detector-php.git",
"reference": "fb0765845e554f04ccd2b594a7ab8ca44d804bab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aaronpk/emoji-detector-php/zipball/fb0765845e554f04ccd2b594a7ab8ca44d804bab",
"reference": "fb0765845e554f04ccd2b594a7ab8ca44d804bab",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"phpunit/phpunit": "4.8"
},
"type": "library",
"autoload": {
"files": [
"src/Emoji.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Aaron Parecki",
"email": "aaron@parecki.com",
"homepage": "https://aaronparecki.com/"
}
],
"description": "Detect and return all emoji found in a string",
"homepage": "https://github.com/aaronpk/emoji-detector-php",
"time": "2017-11-30T21:02:53+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v9.99.99",
@ -2342,7 +2383,7 @@
},
{
"name": "symfony/options-resolver",
"version": "v5.0.3",
"version": "v5.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
@ -2454,7 +2495,7 @@
},
{
"name": "symfony/process",
"version": "v5.0.3",
"version": "v5.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
@ -4792,7 +4833,7 @@
},
{
"name": "symfony/browser-kit",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
@ -4907,7 +4948,7 @@
},
{
"name": "symfony/config",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
@ -4971,16 +5012,16 @@
},
{
"name": "symfony/console",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f"
"reference": "f512001679f37e6a042b51897ed24a2f05eba656"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f",
"reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f",
"url": "https://api.github.com/repos/symfony/console/zipball/f512001679f37e6a042b51897ed24a2f05eba656",
"reference": "f512001679f37e6a042b51897ed24a2f05eba656",
"shasum": ""
},
"require": {
@ -5043,7 +5084,7 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2020-01-10T21:54:01+00:00"
"time": "2020-01-25T12:44:29+00:00"
},
{
"name": "symfony/css-selector",
@ -5100,16 +5141,16 @@
},
{
"name": "symfony/dependency-injection",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
"reference": "6faf589e1f6af78692aed3ab6b3c336c58d5d83c"
"reference": "ec60a7d12f5e8ab0f99456adce724717d9c1784a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6faf589e1f6af78692aed3ab6b3c336c58d5d83c",
"reference": "6faf589e1f6af78692aed3ab6b3c336c58d5d83c",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ec60a7d12f5e8ab0f99456adce724717d9c1784a",
"reference": "ec60a7d12f5e8ab0f99456adce724717d9c1784a",
"shasum": ""
},
"require": {
@ -5169,11 +5210,11 @@
],
"description": "Symfony DependencyInjection Component",
"homepage": "https://symfony.com",
"time": "2020-01-21T07:39:36+00:00"
"time": "2020-01-31T09:49:27+00:00"
},
{
"name": "symfony/dom-crawler",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
@ -5234,7 +5275,7 @@
},
{
"name": "symfony/event-dispatcher",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
@ -5362,7 +5403,7 @@
},
{
"name": "symfony/filesystem",
"version": "v5.0.3",
"version": "v5.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
@ -5587,7 +5628,7 @@
},
{
"name": "symfony/translation",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
@ -5720,7 +5761,7 @@
},
{
"name": "symfony/yaml",
"version": "v4.4.3",
"version": "v4.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",

View file

@ -22,5 +22,6 @@ return array(
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'20ed976102eb0f85eff007c4d1dc1db8' => $vendorDir . '/indieweb/rel-me/RelMe.php',
'd08bec471a180204a14ef3c91e951f99' => $vendorDir . '/p3k/emoji-detector/src/Emoji.php',
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
);

View file

@ -23,6 +23,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'20ed976102eb0f85eff007c4d1dc1db8' => __DIR__ . '/..' . '/indieweb/rel-me/RelMe.php',
'd08bec471a180204a14ef3c91e951f99' => __DIR__ . '/..' . '/p3k/emoji-detector/src/Emoji.php',
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
);

View file

@ -1424,6 +1424,49 @@
"markdown"
]
},
{
"name": "p3k/emoji-detector",
"version": "0.2.1",
"version_normalized": "0.2.1.0",
"source": {
"type": "git",
"url": "https://github.com/aaronpk/emoji-detector-php.git",
"reference": "fb0765845e554f04ccd2b594a7ab8ca44d804bab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aaronpk/emoji-detector-php/zipball/fb0765845e554f04ccd2b594a7ab8ca44d804bab",
"reference": "fb0765845e554f04ccd2b594a7ab8ca44d804bab",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"phpunit/phpunit": "4.8"
},
"time": "2017-11-30T21:02:53+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"src/Emoji.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Aaron Parecki",
"email": "aaron@parecki.com",
"homepage": "https://aaronparecki.com/"
}
],
"description": "Detect and return all emoji found in a string",
"homepage": "https://github.com/aaronpk/emoji-detector-php"
},
{
"name": "paragonie/random_compat",
"version": "v9.99.99",
@ -2417,8 +2460,8 @@
},
{
"name": "symfony/options-resolver",
"version": "v5.0.3",
"version_normalized": "5.0.3.0",
"version": "v5.0.4",
"version_normalized": "5.0.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
@ -2533,8 +2576,8 @@
},
{
"name": "symfony/process",
"version": "v5.0.3",
"version_normalized": "5.0.3.0",
"version": "v5.0.4",
"version_normalized": "5.0.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",

4
vendor/p3k/emoji-detector/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.DS_Store
vendor/
coverage/
composer.lock

14
vendor/p3k/emoji-detector/.travis.yml vendored Normal file
View file

@ -0,0 +1,14 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
- nightly
matrix:
include:
- php: 5.3
dist: precise
before_script: composer install

View file

@ -0,0 +1 @@
By submitting code to this project, you agree to irrevocably release it under the same license as this project. See README.md for more details.

10
vendor/p3k/emoji-detector/LICENSE vendored Normal file
View file

@ -0,0 +1,10 @@
MIT License
-----------
Copyright 2017 by Aaron Parecki
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

124
vendor/p3k/emoji-detector/README.md vendored Normal file
View file

@ -0,0 +1,124 @@
Emoji Detection
===============
This library will find all emoji in an input string and return information about each emoji character. It supports emoji with skin tone modifiers, as well as the composite emoji that are made up of multiple people.
[![Build Status](https://travis-ci.org/aaronpk/emoji-detector-php.svg?branch=master)](https://travis-ci.org/aaronpk/emoji-detector-php)
Installation
------------
```
composer require p3k/emoji-detector
```
Or include `src/Emoji.php` in your project, and make sure the `map.json` and `regexp.json` files are available in the same folder as `Emoji.php`. You don't need any of the other files for use in your own projects.
Usage
-----
### Detect Emoji
```php
$input = "Hello 👍🏼 World 👨‍👩‍👦‍👦";
$emoji = Emoji\detect_emoji($input);
print_r($emoji);
```
The function returns an array with details about each emoji found in the string.
```
Array
(
[0] => Array
(
[emoji] => 👨‍👩‍👦‍👦
[short_name] => man-woman-boy-boy
[num_points] => 7
[points_hex] => Array
(
[0] => 1F468
[1] => 200D
[2] => 1F469
[3] => 200D
[4] => 1F466
[5] => 200D
[6] => 1F466
)
[hex_str] => 1F468-200D-1F469-200D-1F466-200D-1F466
[skin_tone] =>
)
[1] => Array
(
[emoji] => 👍🏼
[short_name] => +1
[num_points] => 2
[points_hex] => Array
(
[0] => 1F44D
[1] => 1F3FC
)
[hex_str] => 1F44D-1F3FC
[skin_tone] => skin-tone-3
)
)
```
* `emoji` - The emoji sequence found, as the original byte sequence. You can output this to show the original emoji.
* `short_name` - The short name of the emoji, as defined by [Slack's emoji data](https://github.com/iamcal/emoji-data).
* `num_points` - The number of unicode code points that this emoji is composed of.
* `points_hex` - An array of each unicode code point that makes up this emoji. These are returned as hex strings. This will also include "invisible" characters such as the ZWJ character and skin tone modifiers.
* `hex_str` - A list of all unicode code points in their hex form separated by hyphens. This string is present in the [Slack emoji data](https://github.com/iamcal/emoji-data) array.
* `skin_tone` - If a skin tone modifier was used in the emoji, this field indicates which skin tone, since the `short_name` will not include the skin tone.
### Test if a string is a single emoji
Since simply counting the number of unicode characters in a string does not tell you how many visible emoji are in the string, determining whether a single character is an emoji is more involved. This function will return the emoji data only if the string contains a single emoji character, and false otherwise.
```php
$emoji = Emoji\is_single_emoji('👨‍👩‍👦‍👦');
print_r($emoji);
```
```
Array
(
[emoji] => 👨‍👩‍👦‍👦
[short_name] => man-woman-boy-boy
[num_points] => 7
[points_hex] => Array
(
[0] => 1F468
[1] => 200D
[2] => 1F469
[3] => 200D
[4] => 1F466
[5] => 200D
[6] => 1F466
)
[hex_str] => 1F468-200D-1F469-200D-1F466-200D-1F466
[skin_tone] =>
)
```
```php
$emoji = Emoji\is_single_emoji('😻🐈');
// false
```
License
-------
Copyright 2017 by Aaron Parecki.
Available under the MIT license.
Emoji data sourced from [iamcal/emoji-data](https://github.com/iamcal/emoji-data) under the MIT license.
Emoji parsing regex sourced from [EmojiOne](https://github.com/Ranks/emojione) under the MIT license.

View file

@ -0,0 +1,42 @@
<?php
// Build the mapping array of hex unicode code point lists to shortnames.
// From Slack's emoji.json
// https://raw.githubusercontent.com/iamcal/emoji-data/master/emoji_pretty.json
$emoji_data = json_decode(file_get_contents('https://raw.githubusercontent.com/iamcal/emoji-data/master/emoji_pretty.json'), true);
$map = [];
foreach($emoji_data as $emoji) {
$short_name = $emoji['short_name'];
// Slack changed flag-de shortname to de, but we still want to keep flag-de
// Most of the flag emojis are still flag-*, they only changed some of them
if(isset($emoji['short_names']) && in_array('flag-'.$short_name, $emoji['short_names'])) {
$short_name = 'flag-' . $short_name;
}
$map[$emoji['unified']] = $short_name;
if(isset($emoji['variations'])) {
foreach($emoji['variations'] as $var) {
$map[$var] = $short_name;
}
}
if(isset($emoji['skin_variations'])) {
foreach($emoji['skin_variations'] as $key=>$var) {
$map[$var['unified']] = $short_name;
}
}
}
file_put_contents(dirname(__FILE__).'/../src/map.json', json_encode($map));
$keys = array_keys($map);
usort($keys,function($a,$b){
return strlen($b)-strlen($a);
});
$all = preg_replace('/\-?([0-9a-f]+)/i', '\x{$1}', implode('|', $keys));
file_put_contents(dirname(__FILE__).'/../src/regexp.json', json_encode($all));

26
vendor/p3k/emoji-detector/composer.json vendored Normal file
View file

@ -0,0 +1,26 @@
{
"name": "p3k/emoji-detector",
"description": "Detect and return all emoji found in a string",
"type": "library",
"license": "MIT",
"homepage": "https://github.com/aaronpk/emoji-detector-php",
"authors": [
{
"name": "Aaron Parecki",
"email": "aaron@parecki.com",
"homepage": "https://aaronparecki.com/"
}
],
"autoload": {
"files": [
"src/Emoji.php"
]
},
"minimum-stability": "dev",
"require": {
"php": ">=5.3"
},
"require-dev": {
"phpunit/phpunit": "4.8"
}
}

10
vendor/p3k/emoji-detector/phpunit.xml vendored Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<phpunit
bootstrap="tests/bootstrap.php"
beStrictAboutTestsThatDoNotTestAnything="true">
<testsuites>
<testsuite name="comments">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
</phpunit>

111
vendor/p3k/emoji-detector/src/Emoji.php vendored Normal file
View file

@ -0,0 +1,111 @@
<?php
namespace Emoji;
define('LONGEST_EMOJI', 8);
function detect_emoji($string) {
// Find all the emoji in the input string
$prevencoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
$data = array();
static $map;
if(!isset($map))
$map = _load_map();
static $regexp;
if(!isset($regexp))
$regexp = _load_regexp();
if(preg_match_all($regexp, $string, $matches)) {
foreach($matches[0] as $ch) {
$points = array();
for($i=0; $i<mb_strlen($ch); $i++) {
$points[] = strtoupper(dechex(uniord(mb_substr($ch, $i, 1))));
}
$hexstr = implode('-', $points);
if(array_key_exists($hexstr, $map)) {
$short_name = $map[$hexstr];
} else {
$short_name = null;
}
$skin_tone = null;
$skin_tones = array(
'1F3FB' => 'skin-tone-2',
'1F3FC' => 'skin-tone-3',
'1F3FD' => 'skin-tone-4',
'1F3FE' => 'skin-tone-5',
'1F3FF' => 'skin-tone-6',
);
foreach($points as $pt) {
if(array_key_exists($pt, $skin_tones))
$skin_tone = $skin_tones[$pt];
}
$data[] = array(
'emoji' => $ch,
'short_name' => $short_name,
'num_points' => mb_strlen($ch),
'points_hex' => $points,
'hex_str' => $hexstr,
'skin_tone' => $skin_tone,
);
}
}
if($prevencoding)
mb_internal_encoding($prevencoding);
return $data;
}
function is_single_emoji($string) {
$prevencoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
// If the string is longer than the longest emoji, it's not a single emoji
if(mb_strlen($string) >= LONGEST_EMOJI) return false;
$all_emoji = detect_emoji($string);
$emoji = false;
// If there are more than one or none, return false immediately
if(count($all_emoji) == 1) {
$emoji = $all_emoji[0];
// Check if there are any other characters in the string
// Remove the emoji found
$string = str_replace($emoji['emoji'], '', $string);
// If there are any characters left, then the string is not a single emoji
if(strlen($string) > 0)
$emoji = false;
}
if($prevencoding)
mb_internal_encoding($prevencoding);
return $emoji;
}
function _load_map() {
return json_decode(file_get_contents(dirname(__FILE__).'/map.json'), true);
}
function _load_regexp() {
return '/(?:' . json_decode(file_get_contents(dirname(__FILE__).'/regexp.json')) . ')/u';
}
function uniord($c) {
$ord0 = ord($c[0]); if ($ord0>=0 && $ord0<=127) return $ord0;
$ord1 = ord($c[1]); if ($ord0>=192 && $ord0<=223) return ($ord0-192)*64 + ($ord1-128);
$ord2 = ord($c[2]); if ($ord0>=224 && $ord0<=239) return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128);
$ord3 = ord($c[3]); if ($ord0>=240 && $ord0<=247) return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128);
return false;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long