Passed
Push — main ( 4768e0...b205bb )
by Mark
02:09
created

TwemojiProcessor::getTwemojiImage()   B

Complexity

Conditions 8
Paths 10

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 16
nc 10
nop 1
dl 0
loc 27
ccs 17
cts 17
cp 1
crap 8
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Emoji\Extension\Twemoji;
6
7
use League\Configuration\ConfigurationAwareInterface;
8
use League\Configuration\ConfigurationInterface;
9
use League\Emoji\EmojiConverterInterface;
10
use League\Emoji\Event\DocumentParsedEvent;
11
use League\Emoji\Node\Emoji;
12
use League\Emoji\Node\Image;
13
use League\Emoji\Util\HtmlElement;
14
15
/**
16
 * Replaces emojis with Twemoji images.
17
 */
18
final class TwemojiProcessor implements ConfigurationAwareInterface
19
{
20
    public const CONVERSION_TYPE = 'twemoji';
21
22
    /**
23
     * @var ConfigurationInterface
24
     *
25
     * @psalm-readonly-allow-private-mutation
26
     * @psalm-suppress PropertyNotSetInConstructor
27
     */
28
    private $config;
29
30 18
    public function __invoke(DocumentParsedEvent $e): void
31
    {
32 18
        foreach ($e->getDocument()->getNodes() as $node) {
33
            // Only convert types that are set to "twemoji".
34 18
            if (! ($node instanceof Emoji) || $node->hexcode === null || $this->getConversionType($node) !== self::CONVERSION_TYPE) {
35 18
                continue;
36
            }
37
38 18
            $twemoji = $this->getTwemojiImage($node);
39
40 18
            $node->replaceWith($twemoji);
41
        }
42 18
    }
43
44
    /** @return string[] */
45 18
    protected function getClasses(): array
46
    {
47
        /** @var string[] $classes */
48 18
        $classes = (array) $this->config->get('twemoji.classes');
49
50 18
        return $classes;
51
    }
52
53 18
    protected function getClassPrefix(): string
54
    {
55 18
        return (string) $this->config->get('twemoji.classPrefix');
56
    }
57
58 18
    protected function getConversionType(Emoji $emoji): ?string
59
    {
60 18
        $parsedType     = $emoji->getParsedType();
61 18
        $configPath     = 'convert.' . (EmojiConverterInterface::TYPES[$parsedType] ?? '');
62 18
        $conversionType = null;
63 18
        if ($this->config->exists($configPath)) {
64 18
            $conversionType = (string) ($this->config->get($configPath) ?? '');
65
        }
66
67 18
        return $conversionType;
68
    }
69
70 18
    protected function getImageType(): string
71
    {
72 18
        return (string) $this->config->get('twemoji.type');
73
    }
74
75
    /** @return int|float|string|null */
76 18
    protected function getSize()
77
    {
78
        /** @var int|float|string|null $size */
79 18
        $size = $this->config->get('twemoji.size');
80
81 18
        return $size;
82
    }
83
84 18
    protected function getTwemojiImage(Emoji $emoji): Image
85
    {
86 18
        $image = new Image($emoji->getParsedValue(), $emoji, $this->getUrl((string) $emoji->hexcode), $emoji->annotation, $emoji->annotation);
87
88
        // Add classes.
89 18
        $image->addClass(...$this->getClasses());
90 18
        if ($emoji->annotation !== null) {
91 18
            $image->addClass(HtmlElement::cleanCssIdentifier($this->getClassPrefix() . $emoji->annotation));
92
        }
93
94
        // Ensure image isn't massive and relative to its surroundings by inlining it.
95 18
        $inline = $this->isInline();
96 18
        $size   = $this->getSize();
97 18
        if ($inline && $size === null) {
98 12
            $image->setAttribute('style', 'width: 1em; height: 1em; vertical-align: middle;');
99 6
        } elseif ($inline && $size !== null) {
100 3
            if (! \is_string($size)) {
101 3
                $size .= 'em';
102
            }
103
104 3
            $image->setAttribute('style', \sprintf('width: %s; height: %s; vertical-align: middle;', $size, $size));
105 3
        } elseif ($size !== null) {
106 3
            $image->setAttribute('height', (string) $size);
107 3
            $image->setAttribute('width', (string) $size);
108
        }
109
110 18
        return $image;
111
    }
112
113 18
    protected function getUrl(string $hexcode): string
114
    {
115 18
        return \sprintf(
116
            '%s/%s/%s.%s',
117 18
            $this->getUrlBase(),
118 18
            ($imageType = $this->getImageType()) === 'png' ? '72x72' : 'svg',
119 18
            \strtolower($hexcode),
120 18
            $imageType
121
        );
122
    }
123
124 18
    protected function getUrlBase(): string
125
    {
126 18
        return (string) $this->config->get('twemoji.urlBase');
127
    }
128
129 18
    protected function isInline(): bool
130
    {
131 18
        return (bool) $this->config->get('twemoji.inline');
132
    }
133
134 18
    public function setConfiguration(ConfigurationInterface $configuration): void
135
    {
136 18
        $this->config = $configuration;
137 18
    }
138
}
139