Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
95 changes: 95 additions & 0 deletions src/Storage/ArrayStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

/*
* This file is part of the PHP Translation package.
*
* (c) PHP Translation team <tobias.nyholm@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Translation\Common\Storage;

use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\MessageCatalogueInterface;
use Translation\Common\Model\Message;
use Translation\Common\Model\MessageInterface;

/**
* An in-memory storage.
*/
final class ArrayStorage implements StorageInterface
{
/**
* @var MessageCatalogue[]
*/
private $catalogues;

/**
* {@inheritdoc}
*/
public function get(string $locale, string $domain, string $key): ?MessageInterface
{
$translation = $this->getCatalogue($locale)->get($key, $domain);

return new Message($key, $domain, $locale, $translation);
}

/**
* {@inheritdoc}
*/
public function create(MessageInterface $message): void
{
$catalogue = $this->getCatalogue($message->getLocale());
if (!$catalogue->defines($message->getKey(), $message->getDomain())) {
$catalogue->set($message->getKey(), $message->getTranslation(), $message->getDomain());
}
}

/**
* {@inheritdoc}
*/
public function update(MessageInterface $message): void
{
$catalogue = $this->getCatalogue($message->getLocale());
$catalogue->set($message->getKey(), $message->getTranslation(), $message->getDomain());
}

/**
* {@inheritdoc}
*/
public function delete(string $locale, string $domain, string $key): void
{
$catalogue = $this->getCatalogue($locale);
$messages = $catalogue->all($domain);
unset($messages[$key]);

$catalogue->replace($messages, $domain);
}

/**
* {@inheritdoc}
*/
public function export(MessageCatalogueInterface $catalogue, array $options = []): void
{
$catalogue->addCatalogue($this->getCatalogue($catalogue->getLocale()));
}

/**
* {@inheritdoc}
*/
public function import(MessageCatalogueInterface $catalogue, array $options = []): void
{
$this->getCatalogue($catalogue->getLocale())->addCatalogue($catalogue);
}

private function getCatalogue(string $locale): MessageCatalogue
{
if (empty($this->catalogues[$locale])) {
$this->catalogues[$locale] = new MessageCatalogue($locale);
}

return $this->catalogues[$locale];
}
}
12 changes: 11 additions & 1 deletion src/Storage/ChainStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
*/
class ChainStorage implements StorageInterface
{
const DIRECTION_UP = 'up';
const DIRECTION_DOWN = 'down';

private $storages = [];

/**
Expand Down Expand Up @@ -83,7 +86,14 @@ public function delete(string $locale, string $domain, string $key): void
*/
public function export(MessageCatalogueInterface $catalogue, array $options = []): void
{
foreach ($this->storages as $storage) {
$options['direction'] = $options['direction'] ?? self::DIRECTION_DOWN;

$storages = $this->storages;
if (isset($options['direction']) && self::DIRECTION_UP === $options['direction']) {
$storages = array_reverse($storages);
}

foreach ($storages as $storage) {
$storage->export($catalogue, $options);
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/Storage/StorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,20 @@ public function delete(string $locale, string $domain, string $key): void;
/**
* Get messages from the storage into the $catalogue.
*
* This action should be considered as a "force merge". Existing messages
* in the storage will be overwritten but no message will be removed.
*
* @var array a list of arbitrary options that could be used. The array SHOULD
* use a format of array<string, array<mixed $value>.
* Example: ['foo' => ['bar', 'baz]]
*/
public function export(MessageCatalogueInterface $catalogue, array $options = []): void;

/**
* Populate the storage with all the messages in $catalogue. This action
* should be considered as a "force merge". Existing messages in the storage
* will be overwritten but no message will be removed.
* Populate the storage with all the messages in $catalogue.
*
* This action should be considered as a "force merge". Existing messages
* in the storage will be overwritten but no message will be removed.
*
* @var array a list of arbitrary options that could be used. The array SHOULD
* use a format of array<string, array<mixed $value>.
Expand Down
76 changes: 76 additions & 0 deletions tests/Unit/Storage/ArrayStorageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

/*
* This file is part of the PHP Translation package.
*
* (c) PHP Translation team <tobias.nyholm@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Translation\common\tests\Unit\Storage;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Translation\MessageCatalogue;
use Translation\Common\Model\Message;
use Translation\Common\Storage\ArrayStorage;

class ArrayStorageTest extends TestCase
{
private $messages;
private $storage;

public function setUp(): void
{
$this->messages = [
'messages_en_foo' => new Message('foo', 'messages', 'en', 'I am the "foo" translation for English in the "messages" domain.'),
'messages_fr_foo' => new Message('foo', 'messages', 'fr', 'Je suis la traduction de la clé "foo" en français dans le domain "messages".'),
'messages_en_bar' => new Message('bar', 'messages', 'en', 'I am the "bar" translation for English in the "messages" domain.'),
'messages_fr_bar' => new Message('bar', 'messages', 'fr', 'Je suis la traduction de la clé "bar" en français dans le domain "messages".'),
'validators_en_foo' => new Message('foo', 'validators', 'en', 'I am the "foo" translation for English in the "validators" domain.'),
'validators_fr_foo' => new Message('foo', 'validators', 'fr', 'Je suis la traduction de la clé "foo" en français dans le domain "validators".'),
'validators_en_bar' => new Message('bar', 'validators', 'en', 'I am the "bar" translation for English in the "validators" domain.'),
'validators_fr_bar' => new Message('bar', 'validators', 'fr', 'Je suis la traduction de la clé "bar" en français dans le domain "validators".'),
];

$this->storage = new ArrayStorage();
foreach ($this->messages as $message) {
$this->storage->create($message);
}
}

public function testDelete()
{
$this->assertEquals($this->messages['messages_en_foo'], $this->storage->get('en', 'messages', 'foo'));
$this->storage->delete('en', 'messages', 'foo');
$this->assertEquals(new Message('foo', 'messages', 'en', 'foo'), $this->storage->get('en', 'messages', 'foo'));
}

public function testUpdate()
{
$this->assertEquals($this->messages['messages_en_foo'], $this->storage->get('en', 'messages', 'foo'));
$updatedMessage = new Message('foo', 'messages', 'en', 'Updated translation');
$this->assertEquals($this->messages['messages_en_foo'], $this->storage->get('en', 'messages', 'foo'));
}

public function testExport()
{
$messageCatalogue = new MessageCatalogue('en');
$messageCatalogue->set('foo', 'I will be overrided.', 'messages');

$this->storage->export($messageCatalogue);

$this->assertEquals($this->messages['messages_en_foo'], $this->storage->get('en', 'messages', 'foo'));
}

public function testImport()
{
$messageCatalogue = new MessageCatalogue('en');
$messageCatalogue->set('foo', 'I will override the existing key.', 'messages');

$this->storage->import($messageCatalogue);

$this->assertEquals(new Message('foo', 'messages', 'en', 'I will override the existing key.'), $this->storage->get('en', 'messages', 'foo'));
}
}
Loading