blob: 6bad4ff323ee93ac3e97030eb4e4aca82ac6cd74 [file] [log] [blame]
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02001<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Translation\Dumper;
13
14use Symfony\Component\Translation\Exception\InvalidArgumentException;
15use Symfony\Component\Translation\Exception\RuntimeException;
16use Symfony\Component\Translation\MessageCatalogue;
17
18/**
19 * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
20 *
21 * Options:
22 * - path (mandatory): the directory where the files should be saved
23 *
24 * @author Michel Salib <michelsalib@hotmail.com>
25 */
26abstract class FileDumper implements DumperInterface
27{
28 /**
29 * A template for the relative paths to files.
30 *
31 * @var string
32 */
33 protected $relativePathTemplate = '%domain%.%locale%.%extension%';
34
35 /**
36 * Sets the template for the relative paths to files.
37 *
38 * @param string $relativePathTemplate A template for the relative paths to files
39 */
40 public function setRelativePathTemplate(string $relativePathTemplate)
41 {
42 $this->relativePathTemplate = $relativePathTemplate;
43 }
44
45 /**
46 * {@inheritdoc}
47 */
48 public function dump(MessageCatalogue $messages, array $options = [])
49 {
50 if (!\array_key_exists('path', $options)) {
51 throw new InvalidArgumentException('The file dumper needs a path option.');
52 }
53
54 // save a file for each domain
55 foreach ($messages->getDomains() as $domain) {
56 $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
57 if (!file_exists($fullpath)) {
58 $directory = \dirname($fullpath);
59 if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
60 throw new RuntimeException(sprintf('Unable to create directory "%s".', $directory));
61 }
62 }
63
64 $intlDomain = $domain.MessageCatalogue::INTL_DOMAIN_SUFFIX;
65 $intlMessages = $messages->all($intlDomain);
66
67 if ($intlMessages) {
68 $intlPath = $options['path'].'/'.$this->getRelativePath($intlDomain, $messages->getLocale());
69 file_put_contents($intlPath, $this->formatCatalogue($messages, $intlDomain, $options));
70
71 $messages->replace([], $intlDomain);
72
73 try {
74 if ($messages->all($domain)) {
75 file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
76 }
77 continue;
78 } finally {
79 $messages->replace($intlMessages, $intlDomain);
80 }
81 }
82
83 file_put_contents($fullpath, $this->formatCatalogue($messages, $domain, $options));
84 }
85 }
86
87 /**
88 * Transforms a domain of a message catalogue to its string representation.
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020089 */
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010090 abstract public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string;
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020091
92 /**
93 * Gets the file extension of the dumper.
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020094 */
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010095 abstract protected function getExtension(): string;
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020096
97 /**
98 * Gets the relative file path using the template.
99 */
100 private function getRelativePath(string $domain, string $locale): string
101 {
102 return strtr($this->relativePathTemplate, [
103 '%domain%' => $domain,
104 '%locale%' => $locale,
105 '%extension%' => $this->getExtension(),
106 ]);
107 }
108}