8000 [Translation] Added template for relative file paths in FileDumper by florianv · Pull Request #9852 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Translation] Added template for relative file paths in FileDumper #9852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 3, 2014
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[Translation] Added template for relative file paths
  • Loading branch information
florianv committed Mar 3, 2014
commit 84f09024b4dd294081daa902284def2cc6c8edde
6 changes: 6 additions & 0 deletions src/Symfony/Component/Translation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
CHANGELOG
=========

2.5.0
-----

* added relative file path template to the file dumpers
* changed IcuResFileDumper to extend FileDumper

2.3.0
-----

Expand Down
42 changes: 40 additions & 2 deletions src/Symfony/Component/Translation/Dumper/FileDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@
*/
abstract class FileDumper implements DumperInterface
{
/**
* A template for the relative paths to files.
*
* @var string
*/
protected $relativePathTemplate = '{domain}.{locale}.{extension}';

/**
* Sets the template for the relative paths to files.
*
* @param string $relativePathTemplate A template for the relative paths to files
*/
public function setRelativePathTemplate($relativePathTemplate)
{
$this->relativePathTemplate = $relativePathTemplate;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it need to be public or do we only need it internally?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this method is only used in a test and could be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can be useful to be able to inspect the template that is currently set.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to agree with @jakzal. Exposing this information from the Dumper does not seem like a good idea. Again, most of the time, the default just work fine, so if you override it, it means that this information is already managed somewhere else.


/**
* {@inheritDoc}
*/
Expand All @@ -35,11 +52,15 @@ public function dump(MessageCatalogue $messages, $options = array())

// save a file for each domain
foreach ($messages->getDomains() as $domain) {
$file = $domain.'.'.$messages->getLocale().'.'.$this->getExtension();
// backup
$fullpath = $options['path'].'/'.$file;
$fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
if (file_exists($fullpath)) {
copy($fullpath, $fullpath.'~');
} else {
$directory = dirname($fullpath);
if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
throw new \RuntimeException(sprintf('Cannot create the directory "%s"', $directory));
}
}
// save file
file_put_contents($fullpath, $this->format($messages, $domain));
Expand All @@ -62,4 +83,21 @@ abstract protected function format(MessageCatalogue $messages, $domain);
* @return string file extension
*/
abstract protected function getExtension();

/**
* Gets the relative file path using the template.
*
* @param string $domain The domain
* @param string $locale The locale
*
* @return string The relative file path
*/
private function getRelativePath($domain, $locale)
{
return strtr($this->relativePathTemplate, array(
'{domain}' => $domain,
'{locale}' => $locale,
'{extension}' => $this->getExtension()
));
}
}
27 changes: 2 additions & 25 deletions src/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,12 @@
*
* @author Stealth35
*/
class IcuResFileDumper implements DumperInterface
class IcuResFileDumper extends FileDumper
{
/**
* {@inheritDoc}
*/
public function dump(MessageCatalogue $messages, $options = array())
{
if (!array_key_exists('path', $options)) {
throw new \InvalidArgumentException('The file dumper need a path options.');
}

// save a file for each domain
foreach ($messages->getDomains() as $domain) {
$file = $messages->getLocale().'.'.$this->getExtension();
$path = $options['path'].'/'.$domain.'/';

if (!file_exists($path)) {
mkdir($path);
}

// backup
if (file_exists($path.$file)) {
copy($path.$file, $path.$file.'~');
}

// save file
file_put_contents($path.$file, $this->format($messages, $domain));
}
}
protected $relativePathTemplate = '{domain}/{locale}.{extension}';

/**
* {@inheritDoc}
Expand Down
38 changes: 38 additions & 0 deletions src/Symfony/Component/Translation/Dumper/NullFileDumper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation\Dumper;

use Symfony\Component\Translation\MessageCatalogue;

/**
* Null file dumper used for testing purposes.
*
* @author Florian Voutzinos <florian@voutzinos.com>
*/
class NullFileDumper extends FileDumper
{
/**
* {@inheritDoc}
*/
protected function format(MessageCatalogue $messages, $domain)
{
return '';
}

/**
* {@inheritDoc}
*/
protected function getExtension()
{
return 'null';
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the idea of having a class in "prod" namespace just for testing purposes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that dumping is already covered by tests. What you should do is to test the behaviour of changing the template (if you change the template, result is dumped to a different file).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dumping is partially covered in the respective adapters but the backup (copy) and directories creation logic are not (from the abstract FileDumper::dump). To test them I see three possibilities :

  • the NullDumper like I did
  • a ConcreteFileDumper in the Tests folder (the same than the NullDumper but outside the prod)
  • repeating the tests in each adapter (which is wrong IMO)

The same question applies to test the logic of changing the template because it is done in the abstract FileDumper. Is there a standard way to test abstract classes in Symfony ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the adapters tests could be refactored to only test the formatting logic.

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public function testDump()
$catalogue->add(array('foo' => 'bar'));

$tempDir = sys_get_temp_dir() . '/IcuResFileDumperTest';
mkdir($tempDir);
$dumper = new IcuResFileDumper();
$dumper->dump($catalogue, array('path' => $tempDir));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Translation\Tests\Dumper;

use Symfony\Component\Translation\Dumper\NullFileDumper;
use Symfony\Component\Translation\MessageCatalogue;

class NullFileDumperTest extends \PHPUnit_Framework_TestCase
{
public function testDumpBackupsFileIfExisting()
{
$tempDir = sys_get_temp_dir();
$file = $tempDir.'/messages.en.null';
$backupFile = $file.'~';

@touch($file);

$catalogue = new MessageCatalogue('en');
$catalogue->add(array('foo' => 'bar'));

$dumper = new NullFileDumper();
$dumper->dump($catalogue, array('path' => $tempDir));

$this->assertTrue(file_exists($backupFile));

@unlink($file);
@unlink($backupFile);
}

public function testDumpCreatesNestedDirectoriesAndFile()
{
$tempDir = sys_get_temp_dir();
$translationsDir = $tempDir.'/test/translations';
$file = $translationsDir.'/messages.en.null';

$catalogue = new MessageCatalogue('en');
$catalogue->add(array('foo' => 'bar'));

$dumper = new NullFileDumper();
$dumper->setRelativePathTemplate('test/translations/{domain}.{locale}.{extension}');
$dumper->dump($catalogue, array('path' => $tempDir));

$this->assertTrue(file_exists($file));

@unlink($file);
@rmdir($translationsDir);
}
}
0