GroupsFactory::extractGroups()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace MazenTouati\NoEmoji\Entities;
5
6
/**
7
 * A utility class that holds and interacts with groups
8
 *
9
 * @author Mazen Touati <[email protected]>
10
 */
11
class GroupsFactory
12
{
13
    /**
14
     * The RegEx pattern used to extract the groups from the file
15
     *
16
     * @var string
17
     */
18
    public $pattern = '/# group: (.*)\n+([^@]+)/m';
19
20
    /**
21
     * Holds the Group's instances
22
     *
23
     * @var array
24
     */
25
    public $groups = [];
26
27
    /**
28
     * Holds the Unicodes extracted from the groups
29
     *
30
     * @var array
31
     */
32
    public $emojiUnicodes = [];
33
34
    /**
35
     * Unicodes getter
36
     *
37
     * @return array
38
     */
39
    public function getUnicodes()
40
    {
41
        return $this->emojiUnicodes;
42
    }
43
44
    /**
45
     * Divides the whole file into smaller groups.
46
     *
47
     * @param  string $source The textual source to perform the scrapping on
48
     * @return GroupsFactory
49
     */
50
    public function extractGroups($source)
51
    {
52
        preg_match_all($this->pattern, $source, $matches);
53
        foreach ($matches[1] as $i => $groupName) {
54
            $this->groups[] = new Group($groupName, $matches[2][$i]);
55
        }
56
57
        return $this;
58
    }
59
60
    /**
61
     * Extracts the Unicodes from the plain text of each group
62
     * @return GroupsFactory
63
     */
64
    public function extractUnicodesFromGroups()
65
    {
66
        foreach ($this->groups as $group) {
67
            $this->emojiUnicodes[$group->name] = $group->extractUnicodes()->getUnicodes();
68
        }
69
70
        return $this;
71
    }
72
73
    /**
74
     * Flattens the Unicode array from being group based to bit based
75
     *
76
     * @return GroupsFactory
77
     */
78
    public function flattenUnicodes()
79
    {
80
        $flattenedUnicodes = [
81
            Group::SINGLE_UNIT_20_BIT => [],
82
            Group::MULTI_UNIT_20_BIT => [],
83
            Group::SINGLE_UNIT_16_BIT => [],
84
            Group::MULTI_UNIT_16_BIT => [],
85
        ];
86
87
        $bitKeys = array_keys($flattenedUnicodes);
88
89
        foreach ($bitKeys as $bits) {
90
            foreach ($this->groups as $group) {
91
                $unicodes = $group->getUnicodes($bits);
92
                $flattenedUnicodes[$bits] = array_merge($flattenedUnicodes[$bits], $unicodes);
93
            }
94
        }
95
96
        $this->emojiUnicodes = $flattenedUnicodes;
97
        $this->mergeMultiWithSingle(Group::MULTI_UNIT_20_BIT, Group::SINGLE_UNIT_20_BIT);
98
99
        return $this;
100
    }
101
102
    /**
103
     * Transforms single unit values from the multi unit array to the single unit array
104
     *
105
     * @param string $multi Multi unit values array's key
106
     * @param string $single Single unit values array's key
107
     */
108
    public function mergeMultiWithSingle(string $multi, string $single): void
109
    {
110
        $digits = (int)$single / 4;
111
112
        foreach ($this->emojiUnicodes[$multi] as $k => $v) {
113
            // If the following value is single unit then transform it
114
            if (!isset($v[$digits])) {
115
                unset($this->emojiUnicodes[$multi][$k]);
116
                $this->emojiUnicodes[$single][] = $v;
117
            }
118
        }
119
120
        // Remove the values holder if all values are transformed to the single unit holder
121
        if (empty($this->emojiUnicodes[$multi])) {
122
            unset($this->emojiUnicodes[$multi]);
123
        }
124
        // Otherwise re-base the holder
125
        else {
126
            $this->emojiUnicodes[$multi] = array_values($this->emojiUnicodes[$multi]);
127
        }
128
    }
129
}
130