Test Failed
Pull Request — master (#14)
by Alexander
02:17
created

MessageSource::write()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 9
ccs 4
cts 5
cp 0.8
crap 2.032
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Translator\Message\Php;
6
7
use InvalidArgumentException;
8
use Yiisoft\Translator\MessageInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Translator\MessageInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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