Passed
Push — master ( 83ee22...2345f0 )
by Alexander
06:48
created

MessageSource   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Test Coverage

Coverage 87.04%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
dl 0
loc 100
ccs 47
cts 54
cp 0.8704
rs 10
c 1
b 0
f 0
wmc 21

7 Methods

Rating   Name   Duplication   Size   Complexity  
A read() 0 15 3
A __construct() 0 3 1
A getMessage() 0 7 2
A generateMessagesFileContent() 0 12 2
A write() 0 8 2
A getFilePath() 0 9 5
A messagesToCode() 0 28 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Translator\Message\Php;
6
7
use InvalidArgumentException;
8
use Yiisoft\Translator\MessageReaderInterface;
9
use Yiisoft\Translator\MessageWriterInterface;
10
use function array_key_exists;
11
use function is_string;
12
13
final class MessageSource implements MessageReaderInterface, MessageWriterInterface
14
{
15
    private string $path;
16
    private array $messages;
17
18 3
    public function __construct(string $path)
19
    {
20 3
        $this->path = $path;
21 3
    }
22
23 3
    public function getMessage(string $id, string $category, string $locale, array $parameters = []): ?string
24
    {
25 3
        if (!isset($this->messages[$category][$locale])) {
26 3
            $this->read($category, $locale);
27
        }
28
29 3
        return $this->messages[$category][$locale][$id] ?? null;
30
    }
31
32 3
    private function getFilePath(string $category, string $locale, bool $withCreateDir = false): ?string
33
    {
34 3
        $filePath = $this->path . DIRECTORY_SEPARATOR . $locale;
35 3
        if ($withCreateDir && !file_exists($filePath) && !mkdir($filePath, 0775, true) && !is_dir($filePath)) {
36
            throw new \RuntimeException(sprintf('Directory "%s" was not created', $filePath));
37
        }
38 3
        $filePath .= DIRECTORY_SEPARATOR . $category . '.php';
39
40 3
        return $filePath;
41
    }
42
43 3
    private function read(string $category, string $locale): void
44
    {
45 3
        $path = $this->getFilePath($category, $locale);
46
47 3
        if (is_file($path)) {
48 3
            $messages = include $path;
49
50 3
            if (!\is_array($messages)) {
51 3
                throw new \RuntimeException('Invalid file format: ' . $path);
52
            }
53
        } else {
54
            $messages = [];
55
        }
56
57 3
        $this->messages[$category][$locale] = $messages;
58 3
    }
59
60 3
    public function write(string $category, string $locale, array $messages): void
61
    {
62 3
        $content = $this->generateMessagesFileContent($messages);
63
64 3
        $path = $this->getFilePath($category, $locale, true);
65
66 3
        if (file_put_contents($path, $content, LOCK_EX) === false) {
67
            throw new \RuntimeException('Can not write to ' . $path);
68
        }
69 3
    }
70
71 3
    private function generateMessagesFileContent(array $messages): string
72
    {
73 3
        $content = "<?php\nreturn ";
74 3
        if (empty($messages)) {
75
            $content .= '[]';
76
        } else {
77 3
            $content .= $this->messagesToCode($messages);
78 3
            $content .= ';';
79
        }
80 3
        $content .= "\n";
81
82 3
        return $content;
83
    }
84
85 3
    private function messagesToCode(array $messages): string
86
    {
87 3
        $code = '[';
88 3
        foreach ($messages as $messageId => $messageData) {
89 3
            if (!array_key_exists('message', $messageData)) {
90
                throw new InvalidArgumentException("Message is not valid for ID \"$messageId\". \"message\" key is missing.");
91
            }
92
93 3
            if (!is_string($messageData['message'])) {
94
                throw new InvalidArgumentException("Message is not a string for ID \"$messageId\".");
95
            }
96
97 3
            if (array_key_exists('comment', $messageData)) {
98 2
                if (!is_string($messageData['comment'])) {
99
                    throw new InvalidArgumentException("Message comment is not a string for ID \"$messageId\".");
100
                }
101
102 2
                $code .= "\n" . '    /* ' . $messageData['comment'] . ' */';
103
            }
104
105 3
            $code .= "\n" . '    ';
106 3
            $code .= "'{$messageId}'";
107 3
            $code .= ' => ';
108 3
            $code .= "'{$messageData['message']}'";
109 3
            $code .= ',';
110
        }
111 3
        $code .= "\n" . ']';
112 3
        return $code;
113
    }
114
}
115