Emoji   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 49
dl 0
loc 128
ccs 40
cts 40
cp 1
rs 10
c 0
b 0
f 0
wmc 18

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getShortcodes() 0 7 2
A setRenderer() 0 3 1
A __construct() 0 26 4
A render() 0 10 2
A jsonSerialize() 0 3 1
A renderProperty() 0 3 1
A getSkin() 0 8 2
A getShortcode() 0 9 4
A __toString() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Emoji\Dataset;
6
7
use League\Emoji\Emojibase\EmojibaseDatasetInterface;
8
use League\Emoji\Emojibase\EmojibaseSkinsInterface;
9
use League\Emoji\Util\ImmutableArrayIterator;
10
use League\Emoji\Util\Normalize;
11
12
/**
13
 * @property ?string $annotation
14
 * @property ?string $emoji
15
 * @property ?string $emoticon
16
 * @property ?int $gender
17
 * @property ?int $group
18
 * @property ?string $hexcode
19
 * @property ?string $htmlEntity
20
 * @property ?int $order
21
 * @property ?string $shortcode
22
 * @property string[] $shortcodes
23
 * @property Dataset $skins
24
 * @property ?int $subgroup
25
 * @property string[] $tags
26
 * @property ?string $text
27
 * @property int[] $tone
28
 * @property int $type
29
 * @property ?string $unicode
30
 * @property ?float $version
31
 */
32
final class Emoji extends ImmutableArrayIterator implements \JsonSerializable, \Stringable
33
{
34
    public const PROPERTY_TYPES = [
35
        'annotation' => '!?string',
36
        'emoji'      => '!?string',
37
        'emoticon'   => '!?string',
38
        'gender'     => '?int',
39
        'group'      => '?int',
40
        'hexcode'    => '!?string',
41
        'order'      => '?int',
42
        'shortcodes' => 'string[]<\League\Emoji\Util\Normalize::shortcodes>',
43
        'skins'      => '\League\Emoji\Dataset\Dataset',
44
        'subgroup'   => '?int',
45
        'tags'       => 'string[]',
46
        'text'       => '!?string',
47
        'tone'       => 'int[]',
48
        'type'       => 'int',
49
        'version'    => '!?float',
50
    ];
51
52
    /**
53
     * @var callable
54
     *
55
     * @psalm-readonly-allow-private-mutation
56
     */
57
    private $renderer = '\League\Emoji\Dataset\Emoji::renderProperty';
58
59
    /**
60
     * @param mixed[] $data
61
     */
62 66
    public function __construct(array $data = [])
63
    {
64 66
        $data = Normalize::properties($data, self::PROPERTY_TYPES);
65
66
        /** @var ?string $hexcode */
67 66
        $hexcode = $data['hexcode'] ?? null;
68
69
        /** @var ?string $emoji */
70 66
        $emoji = $data['emoji'] ?? null;
71
72
        /** @var ?string $text */
73 66
        $text = $data['text'] ?? null;
74
75 66
        $type = (int) ($data['type'] ?? EmojibaseDatasetInterface::EMOJI);
76
77 66
        $data['htmlEntity'] = null;
78 66
        if ($hexcode !== null) {
79 60
            $data['htmlEntity'] = '&#x' . \implode(';&#x', \explode('-', $hexcode)) . ';';
80
        }
81
82 66
        $data['unicode'] = $text;
83 66
        if ($type === EmojibaseDatasetInterface::EMOJI && $emoji) {
84 60
            $data['unicode'] = $emoji;
85
        }
86
87 66
        parent::__construct($data);
88 66
    }
89
90 9
    public static function renderProperty(Emoji $emoji, string $property = 'unicode'): string
91
    {
92 9
        return (string) ($emoji->$property ?? '');
93
    }
94
95 3
    public function __toString(): string
96
    {
97 3
        return (string) $this->render();
98
    }
99
100
    /**
101
     * @param string[]|null $exclude
102
     */
103 54
    public function getShortcode(?array $exclude = null, bool $wrap = false): ?string
104
    {
105 54
        $shortcode = \current($this->getShortcodes($exclude)) ?: null;
106
107 54
        if ($shortcode !== null && $wrap) {
108 36
            $shortcode = \sprintf(':%s:', $shortcode);
109
        }
110
111 54
        return $shortcode;
112
    }
113
114
    /**
115
     * @param ?string[] $exclude
116
     *
117
     * @return string[]
118
     */
119 54
    public function getShortcodes(?array $exclude = null): array
120
    {
121 54
        if ($exclude !== null) {
122 36
            return \array_diff($this->shortcodes, $exclude);
123
        }
124
125 18
        return $this->shortcodes;
126
    }
127
128 12
    public function getSkin(int $tone = EmojibaseSkinsInterface::LIGHT_SKIN): ?self
129
    {
130
        /** @var ?static $skin */
131
        $skin = \current($this->skins->filter(static function (Emoji $emoji) use ($tone) {
132 6
            return \in_array($tone, $emoji->tone, true);
133 12
        })->getArrayCopy()) ?: null;
134
135 12
        return $skin;
136
    }
137
138
    /** {@inheritDoc} */
139 3
    public function jsonSerialize(): string
140
    {
141 3
        return (string) $this->render();
142
    }
143
144
    /** @return \Stringable|string */
145 9
    public function render()
146
    {
147
        /** @var \Stringable|string|null $rendered */
148 9
        $rendered = \call_user_func_array($this->renderer, [$this]);
149
150 9
        if ($rendered instanceof \Stringable) {
151 3
            return $rendered;
152
        }
153
154 9
        return $rendered ?? '';
155
    }
156
157 3
    public function setRenderer(callable $renderer): void
158
    {
159 3
        $this->renderer = $renderer;
160 3
    }
161
}
162