Passed
Pull Request — master (#43)
by Buster
09:23
created

Psr6Cache::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 20
rs 9.9666

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\MoTranslator\Cache;
6
7
use PhpMyAdmin\MoTranslator\MoParser;
8
use Psr\Cache\CacheItemPoolInterface;
9
10
use function array_combine;
11
use function array_keys;
12
use function array_map;
13
use function is_string;
14
use function md5;
15
16
final class Psr6Cache implements CacheInterface
17
{
18
    public const LOADED_KEY = '__TRANSLATIONS_LOADED__';
19
20
    /** @var CacheItemPoolInterface */
21
    private $psr6Cache;
22
23
    /** @var MoParser */
24
    private $parser;
25
26
    /** @var string */
27
    private $locale;
28
29
    /** @var string */
30
    private $domain;
31
32
    /** @var int */
33
    private $ttl;
34
35
    /** @var bool */
36
    private $reloadOnMiss;
37
38
    /** @var string */
39
    private $prefix;
40
41
    /** @var string */
42
    private $separator;
43
44
    public function __construct(
45
        CacheItemPoolInterface $psr6Cache,
46
        MoParser $parser,
47
        string $locale,
48
        string $domain,
49
        int $ttl = 0,
50
        bool $reloadOnMiss = true,
51
        string $prefix = 'mo_',
52
        string $separator = '.'
53
    ) {
54
        $this->psr6Cache = $psr6Cache;
55
        $this->parser = $parser;
56
        $this->locale = $locale;
57
        $this->domain = $domain;
58
        $this->ttl = $ttl;
59
        $this->reloadOnMiss = $reloadOnMiss;
60
        $this->prefix = $prefix;
61
        $this->separator = $separator;
62
63
        $this->ensureTranslationsLoaded();
64
    }
65
66
    public function get(string $msgid): string
67
    {
68
        $cacheItem = $this->psr6Cache->getItem($this->getKey($msgid));
69
        $cacheItemValue = $cacheItem->isHit() ? $cacheItem->get() : null;
70
        if (is_string($cacheItemValue)) {
71
            return $cacheItemValue;
72
        }
73
74
        if (! $this->reloadOnMiss) {
75
            return $msgid;
76
        }
77
78
        $cacheItem->set($msgid);
79
        if ($this->ttl > 0) {
80
            $cacheItem->expiresAfter($this->ttl);
81
        }
82
83
        $this->psr6Cache->save($cacheItem);
84
85
        // reload .mo file, in case entry has been evicted
86
        $this->parser->parseIntoCache($this);
87
88
        $cacheItem = $this->psr6Cache->getItem($this->getKey($msgid));
89
        $cacheItemValue = $cacheItem->isHit() ? $cacheItem->get() : null;
90
91
        return is_string($cacheItemValue)
92
            ? $cacheItemValue
93
            : $msgid;
94
    }
95
96
    public function set(string $msgid, string $msgstr): void
97
    {
98
        $cacheItem = $this->psr6Cache->getItem($this->getKey($msgid));
99
        $cacheItem->set($msgstr);
100
        if ($this->ttl > 0) {
101
            $cacheItem->expiresAfter($this->ttl);
102
        }
103
104
        $this->psr6Cache->save($cacheItem);
105
    }
106
107
    public function has(string $msgid): bool
108
    {
109
        return $this->psr6Cache->hasItem($this->getKey($msgid));
110
    }
111
112
    public function setAll(array $translations): void
113
    {
114
        $keys = array_map(function (string $msgid): string {
115
            return $this->getKey($msgid);
116
        }, array_keys($translations));
117
        $translations = array_combine($keys, $translations);
118
119
        foreach ($this->psr6Cache->getItems($keys) as $cacheItem) {
120
            $cacheItem->set($translations[$cacheItem->getKey()]);
121
            if ($this->ttl > 0) {
122
                $cacheItem->expiresAfter($this->ttl);
123
            }
124
125
            $this->psr6Cache->saveDeferred($cacheItem);
126
        }
127
128
        $this->psr6Cache->commit();
129
    }
130
131
    private function getKey(string $msgid): string
132
    {
133
        // Hash the message ID to avoid using restricted characters in various cache adapters.
134
        return $this->prefix . $this->locale . $this->separator . $this->domain . $this->separator . md5($msgid);
135
    }
136
137
    private function ensureTranslationsLoaded(): void
138
    {
139
        // Try to prevent cache slam if multiple processes are trying to load translations. There is still a race
140
        // between the exists check and creating the entry, but at least it's small
141
        $cacheItem = $this->psr6Cache->getItem($this->getKey(self::LOADED_KEY));
142
        if ($cacheItem->isHit()) {
143
            return;
144
        }
145
146
        $this->parser->parseIntoCache($this);
147
148
        $cacheItem->set(1);
149
        if ($this->ttl > 0) {
150
            $cacheItem->expiresAfter($this->ttl);
151
        }
152
153
        $this->psr6Cache->save($cacheItem);
154
    }
155
}
156