Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ea9883f

Browse files
committed
merged branch jfsimon/issue-6592 (PR #7331)
This PR was merged into the master branch. Commits ------- 57aa3d5 [FrameworkBundle] adds --clean option translation:update command Discussion ---------- [FrameworkBundle] adds --clean option translation:update command This PR adds `--clean` option to `translation:update` command. This options activates unused translation removal. | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #6592
2 parents 94ca275 + 57aa3d5 commit ea9883f

File tree

8 files changed

+526
-14
lines changed

8 files changed

+526
-14
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Command;
1313

1414
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
15+
use Symfony\Component\Translation\Catalogue\DiffOperation;
16+
use Symfony\Component\Translation\Catalogue\MergeOperation;
1517
use Symfony\Component\Console\Input\InputInterface;
1618
use Symfony\Component\Console\Output\OutputInterface;
1719
use Symfony\Component\Console\Input\InputArgument;
@@ -26,12 +28,6 @@
2628
*/
2729
class TranslationUpdateCommand extends ContainerAwareCommand
2830
{
29-
/**
30-
* Compiled catalogue of messages.
31-
* @var MessageCatalogue
32-
*/
33-
protected $catalogue;
34-
3531
/**
3632
* {@inheritDoc}
3733
*/
@@ -57,6 +53,10 @@ protected function configure()
5753
new InputOption(
5854
'force', null, InputOption::VALUE_NONE,
5955
'Should the update be done'
56+
),
57+
new InputOption(
58+
'clean', null, InputOption::VALUE_NONE,
59+
'Should clean not found messages'
6060
)
6161
))
6262
->setDescription('Updates the translation file')
@@ -100,26 +100,41 @@ protected function execute(InputInterface $input, OutputInterface $output)
100100
$bundleTransPath = $foundBundle->getPath().'/Resources/translations';
101101
$output->writeln(sprintf('Generating "<info>%s</info>" translation files for "<info>%s</info>"', $input->getArgument('locale'), $foundBundle->getName()));
102102

103-
// create catalogue
104-
$catalogue = new MessageCatalogue($input->getArgument('locale'));
105-
106103
// load any messages from templates
104+
$extractedCatalogue = new MessageCatalogue($input->getArgument('locale'));
107105
$output->writeln('Parsing templates');
108106
$extractor = $this->getContainer()->get('translation.extractor');
109107
$extractor->setPrefix($input->getOption('prefix'));
110-
$extractor->extract($foundBundle->getPath().'/Resources/views/', $catalogue);
108+
$extractor->extract($foundBundle->getPath().'/Resources/views/', $extractedCatalogue);
111109

112110
// load any existing messages from the translation files
111+
$currentCatalogue = new MessageCatalogue($input->getArgument('locale'));
113112
$output->writeln('Loading translation files');
114113
$loader = $this->getContainer()->get('translation.loader');
115-
$loader->loadMessages($bundleTransPath, $catalogue);
114+
$loader->loadMessages($bundleTransPath, $currentCatalogue);
115+
116+
// process catalogues
117+
$operation = $input->getOption('clean')
118+
? new DiffOperation($currentCatalogue, $extractedCatalogue)
119+
: new MergeOperation($currentCatalogue, $extractedCatalogue);
116120

117121
// show compiled list of messages
118122
if ($input->getOption('dump-messages') === true) {
119-
foreach ($catalogue->getDomains() as $domain) {
123+
foreach ($operation->getDomains() as $domain) {
120124
$output->writeln(sprintf("\nDisplaying messages for domain <info>%s</info>:\n", $domain));
121-
$output->writeln(Yaml::dump($catalogue->all($domain), 10));
125+
$newKeys = array_keys($operation->getNewMessages($domain));
126+
$allKeys = array_keys($operation->getMessages($domain));
127+
foreach (array_diff($allKeys, $newKeys) as $id) {
128+
$output->writeln($id);
129+
}
130+
foreach ($newKeys as $id) {
131+
$output->writeln(sprintf('<fg=green>%s</>', $id));
132+
}
133+
foreach (array_keys($operation->getObsoleteMessages($domain)) as $id) {
134+
$output->writeln(sprintf('<fg=red>%s</>', $id));
135+
}
122136
}
137+
123138
if ($input->getOption('output-format') == 'xliff') {
124139
$output->writeln('Xliff output version is <info>1.2</info>');
125140
}
@@ -128,7 +143,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
128143
// save the files
129144
if ($input->getOption('force') === true) {
130145
$output->writeln('Writing files');
131-
$writer->writeTranslations($catalogue, $input->getOption('output-format'), array('path' => $bundleTransPath));
146+
$writer->writeTranslations($operation->getResult(), $input->getOption('output-format'), array('path' => $bundleTransPath));
132147
}
133148
}
134149
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Catalogue;
13+
14+
use Symfony\Component\Translation\MessageCatalogue;
15+
use Symfony\Component\Translation\MessageCatalogueInterface;
16+
17+
/**
18+
* Base catalogues binary operation class.
19+
*
20+
* @author Jean-François Simon <[email protected]>
21+
*/
22+
abstract class AbstractOperation implements OperationInterface
23+
{
24+
/**
25+
* @var MessageCatalogueInterface
26+
*/
27+
protected $source;
28+
29+
/**
30+
* @var MessageCatalogueInterface
31+
*/
32+
protected $target;
33+
34+
/**
35+
* @var MessageCatalogue
36+
*/
37+
protected $result;
38+
39+
/**
40+
* @var null|array
41+
*/
42+
private $domains;
43+
44+
/**
45+
* @var array
46+
*/
47+
protected $messages;
48+
49+
/**
50+
* @param MessageCatalogueInterface $source
51+
* @param MessageCatalogueInterface $target
52+
*
53+
* @throws \LogicException
54+
*/
55+
public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
56+
{
57+
if ($source->getLocale() !== $target->getLocale()) {
58+
throw new \LogicException('Operated catalogues must belong to the same locale.');
59+
}
60+
61+
$this->source = $source;
62+
$this->target = $target;
63+
$this->result = new MessageCatalogue($source->getLocale());
64+
$this->domains = null;
65+
$this->messages = array();
66+
}
67+
68+
/**
69+
* {@inheritdoc}
70+
*/
71+
public function getDomains()
72+
{
73+
if (null === $this->domains) {
74+
$this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains())));
75+
}
76+
77+
return $this->domains;
78+
}
79+
80+
/**
81+
* {@inheritdoc}
82+
*/
83+
public function getMessages($domain)
84+
{
85+
if (!in_array($domain, $this->getDomains())) {
86+
throw new \InvalidArgumentException('Invalid domain: '.$domain.'.');
87+
}
88+
89+
if (!isset($this->messages[$domain]['all'])) {
90+
$this->processDomain($domain);
91+
}
92+
93+
return $this->messages[$domain]['all'];
94+
}
95+
96+
/**
97+
* {@inheritdoc}
98+
*/
99+
public function getNewMessages($domain)
100+
{
101+
if (!in_array($domain, $this->getDomains())) {
102+
throw new \InvalidArgumentException('Invalid domain: '.$domain.'.');
103+
}
104+
105+
if (!isset($this->messages[$domain]['new'])) {
106+
$this->processDomain($domain);
107+
}
108+
109+
return $this->messages[$domain]['new'];
110+
}
111+
112+
/**
113+
* {@inheritdoc}
114+
*/
115+
public function getObsoleteMessages($domain)
116+
{
117+
if (!in_array($domain, $this->getDomains())) {
118+
throw new \InvalidArgumentException('Invalid domain: '.$domain.'.');
119+
}
120+
121+
if (!isset($this->messages[$domain]['obsolete'])) {
122+
$this->processDomain($domain);
123+
}
124+
125+
return $this->messages[$domain]['obsolete'];
126+
}
127+
128+
/**
129+
* {@inheritdoc}
130+
*/
131+
public function getResult()
132+
{
133+
foreach ($this->getDomains() as $domain) {
134+
if (!isset($this->messages[$domain])) {
135+
$this->processDomain($domain);
136+
}
137+
}
138+
139+
return $this->result;
140+
}
141+
142+
/**
143+
* @param string $domain
144+
*/
145+
abstract protected function processDomain($domain);
146+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Catalogue;
13+
14+
/**
15+
* Diff operation between two catalogues.
16+
*
17+
* @author Jean-François Simon <[email protected]>
18+
*/
19+
class DiffOperation extends AbstractOperation
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
protected function processDomain($domain)
25+
{
26+
$this->messages[$domain] = array(
27+
'all' => array(),
28+
'new' => array(),
29+
'obsolete' => array(),
30+
);
31+
32+
foreach ($this->source->all($domain) as $id => $message) {
33+
if ($this->target->has($id, $domain)) {
34+
$this->messages[$domain]['all'][$id] = $message;
35+
$this->result->add(array($id => $message), $domain);
36+
} else {
37+
$this->messages[$domain]['obsolete'][$id] = $message;
38+
}
39+
}
40+
41+
foreach ($this->target->all($domain) as $id => $message) {
42+
if (!$this->source->has($id, $domain)) {
43+
$this->messages[$domain]['all'][$id] = $message;
44+
$this->messages[$domain]['new'][$id] = $message;
45+
$this->result->add(array($id => $message), $domain);
46+
}
47+
}
48+
}
49+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Catalogue;
13+
14+
/**
15+
* Merge operation between two catalogues.
16+
*
17+
* @author Jean-François Simon <[email protected]>
18+
*/
19+
class MergeOperation extends AbstractOperation
20+
{
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
protected function processDomain($domain)
25+
{
26+
$this->messages[$domain] = array(
27+
'all' => array(),
28+
'new' => array(),
29+
'obsolete' => array(),
30+
);
31+
32+
foreach ($this->source->all($domain) as $id => $message) {
33+
$this->messages[$domain]['all'][$id] = $message;
34+
$this->result->add(array($id => $message), $domain);
35+
}
36+
37+
foreach ($this->target->all($domain) as $id => $message) {
38+
if (!$this->source->has($id, $domain)) {
39+
$this->messages[$domain]['all'][$id] = $message;
40+
$this->messages[$domain]['new'][$id] = $message;
41+
$this->result->add(array($id => $message), $domain);
42+
}
43+
}
44+
}
45+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Translation\Catalogue;
13+
14+
use Symfony\Component\Translation\MessageCatalogueInterface;
15+
16+
/**
17+
* Represents an operation on catalogue(s).
18+
*
19+
* @author Jean-François Simon <[email protected]>
20+
*/
21+
interface OperationInterface
22+
{
23+
/**
24+
* Returns domains affected by operation.
25+
*
26+
* @return array
27+
*/
28+
public function getDomains();
29+
30+
/**
31+
* Returns all valid messages after operation.
32+
*
33+
* @param string $domain
34+
*
35+
* @return array
36+
*/
37+
public function getMessages($domain);
38+
39+
/**
40+
* Returns new messages after operation.
41+
*
42+
* @param string $domain
43+
*
44+
* @return array
45+
*/
46+
public function getNewMessages($domain);
47+
48+
/**
49+
* Returns obsolete messages after operation.
50+
*
51+
* @param string $domain
52+
*
53+
* @return array
54+
*/
55+
public function getObsoleteMessages($domain);
56+
57+
/**
58+
* Returns resulting catalogue.
59+
*
60+
* @return MessageCatalogueInterface
61+
*/
62+
public function getResult();
63+
}

0 commit comments

Comments
 (0)