Passed
Pull Request — latest (#3)
by Mark
35:03
created

Dataset   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 30
c 0
b 0
f 0
dl 0
loc 91
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A filter() 0 3 1
A offsetGet() 0 11 2
A __construct() 0 4 1
A unarchive() 0 25 6
A indexBy() 0 7 2
A archive() 0 9 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace UnicornFail\Emoji\Dataset;
6
7
use UnicornFail\Emoji\Exception\FileNotFoundException;
8
use UnicornFail\Emoji\Exception\MalformedArchiveException;
9
use UnicornFail\Emoji\Exception\UnarchiveException;
10
use UnicornFail\Emoji\Parser\Parser;
11
use UnicornFail\Emoji\Util\ImmutableArrayIterator;
12
use UnicornFail\Emoji\Util\Normalize;
13
14
final class Dataset extends ImmutableArrayIterator implements DatasetInterface
15
{
16
    /** @var string */
17
    private $index;
18
19
    /** @var Dataset[] */
20
    private $indices = [];
21
22
    /**
23
     * @param mixed $emojis
24
     */
25
    public function __construct($emojis = [], string $index = 'hexcode')
26
    {
27
        $this->index = $index;
28
        parent::__construct(Normalize::dataset($emojis, $index), \ArrayIterator::ARRAY_AS_PROPS | \ArrayIterator::STD_PROP_LIST);
29
    }
30
31
    public static function unarchive(string $filename): self
32
    {
33
        if (! \file_exists($filename)) {
34
            throw new FileNotFoundException($filename);
35
        }
36
37
        if (
38
            ! ($contents = \file_get_contents($filename)) ||
39
            ! ($decoded = \gzdecode($contents))
40
        ) {
41
            throw new UnarchiveException($filename);
42
        }
43
44
        try {
45
            /** @var ?Dataset $dataset */
46
            $dataset = \unserialize((string) $decoded);
47
        } catch (\Throwable $throwable) {
48
            throw new MalformedArchiveException($filename, $throwable);
49
        }
50
51
        if (! $dataset instanceof Dataset) {
52
            throw new MalformedArchiveException($filename);
53
        }
54
55
        return $dataset;
56
    }
57
58
    /**
59
     * @param string[] $indices
60
     *
61
     * @return false|string
62
     */
63
    public function archive(array $indices = Parser::INDICES)
64
    {
65
        foreach ($indices as $index) {
66
            $this->indexBy($index);
67
        }
68
69
        $serialize = \serialize($this);
70
71
        return \gzencode($serialize, 9);
72
    }
73
74
    /**
75
     * @param callable(Emoji):bool $callback
76
     */
77
    public function filter(callable $callback): Dataset
78
    {
79
        return new self(new \CallbackFilterIterator($this, $callback));
80
    }
81
82
    public function indexBy(string $index = 'hexcode'): Dataset
83
    {
84
        if (! isset($this->indices[$index])) {
85
            $this->indices[$index] = new self($this, $index);
86
        }
87
88
        return $this->indices[$index];
89
    }
90
91
    /**
92
     * @param string $key
93
     */
94
    public function offsetGet($key): ?Emoji // phpcs:ignore
95
    {
96
        // Normalize shortcodes to match index.
97
        if (\strpos($this->index, 'shortcode') !== false) {
98
            $key = \current(Normalize::shortcodes($key));
99
        }
100
101
        /** @var ?Emoji $emoji */
102
        $emoji = parent::offsetGet($key);
103
104
        return $emoji;
105
    }
106
}
107