phpmyadmin / motranslator

Compare cb27035 ... +0 ... 0c7bad4

Flags

Flags have been temporarily removed from this view while the flagging feature is refactored for better performance and user experience.

You can still use flags when viewing individual files. Flag-level thresholds will also remain on pull and merge requests in your repository provider.

More information can be found in our documentation.

Showing 2 of 5 files from the diff.

@@ -0,0 +1,54 @@
Loading
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 +
final class Psr6CacheFactory implements CacheFactoryInterface
11 +
{
12 +
    /** @var CacheItemPoolInterface */
13 +
    private $psr6Cache;
14 +
15 +
    /** @var int */
16 +
    private $ttl;
17 +
18 +
    /** @var bool */
19 +
    private $reloadOnMiss;
20 +
21 +
    /** @var string */
22 +
    private $prefix;
23 +
24 +
    /** @var string */
25 +
    private $separator;
26 +
27 +
    public function __construct(
28 +
        CacheItemPoolInterface $psr6Cache,
29 +
        int $ttl = 0,
30 +
        bool $reloadOnMiss = true,
31 +
        string $prefix = 'mo_',
32 +
        string $separator = '.'
33 +
    ) {
34 +
        $this->psr6Cache = $psr6Cache;
35 +
        $this->ttl = $ttl;
36 +
        $this->reloadOnMiss = $reloadOnMiss;
37 +
        $this->prefix = $prefix;
38 +
        $this->separator = $separator;
39 +
    }
40 +
41 +
    public function getInstance(MoParser $parser, string $locale, string $domain): CacheInterface
42 +
    {
43 +
        return new Psr6Cache(
44 +
            $this->psr6Cache,
45 +
            $parser,
46 +
            $locale,
47 +
            $domain,
48 +
            $this->ttl,
49 +
            $this->reloadOnMiss,
50 +
            $this->prefix,
51 +
            $this->separator
52 +
        );
53 +
    }
54 +
}

@@ -0,0 +1,155 @@
Loading
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 +
}

Learn more Showing 2 files with coverage changes found.

New file src/Cache/Psr6Cache.php
New
Loading file...
New file src/Cache/Psr6CacheFactory.php
New
Loading file...
Files Complexity Coverage
src ø -0.66% 98.69%
Project Totals (10 files) 132 98.69%
Loading