-
-
Notifications
You must be signed in to change notification settings - Fork 339
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Translate Adapter for multi-column csv (#890)
- Loading branch information
1 parent
477413a
commit f8e2be2
Showing
9 changed files
with
319 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<?php | ||
|
||
namespace Phalcon\Translate\Adapter; | ||
|
||
use Phalcon\Translate\AdapterInterface; | ||
use Phalcon\Translate\Adapter\Csv; | ||
use Phalcon\Translate\Exception; | ||
|
||
class CsvMulti extends Csv implements AdapterInterface, \ArrayAccess | ||
{ | ||
/** | ||
* @var array | ||
*/ | ||
private $locales = array(); | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $locale = null; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $indexes = array(); | ||
|
||
/** | ||
* Load translates from file | ||
* | ||
* @param string file | ||
* @param int length | ||
* @param string delimiter | ||
* @param string enclosure | ||
*/ | ||
// @codingStandardsIgnoreStart | ||
// Method name "_load" should not be prefixed with an underscore to indicate visibility | ||
// Still, it needs to extend the parent one | ||
private function _load($file, $length, $delimiter, $enclosure) | ||
{ | ||
// @codingStandardsIgnoreEnd | ||
$fileHandler = fopen($file, "rb"); | ||
|
||
if (gettype($fileHandler) !== "resource") { | ||
throw new Exception("Error opening translation file '" . $file . "'"); | ||
} | ||
|
||
$line = 0; | ||
$locales = array(); | ||
while ($data = fgetcsv($fileHandler, $length, $delimiter, $enclosure)) { | ||
if ($line++ == 0) { | ||
// first csv line | ||
// register the horizontal locales sort order | ||
// the first element (must be empty) is removed | ||
foreach (array_slice($data, 1) as $pos => $locale) { | ||
$this->locales[$pos] = $locale; | ||
} | ||
} else { | ||
// the first row is the translation index (label) | ||
$index = array_shift($data); | ||
// store this index internally | ||
$this->indexes[] = $index; | ||
// the first element is removed as well, so the pos is according to the first line | ||
foreach ($data as $pos => $translation) { | ||
$this->_translate[$this->locales[$pos]][$index] = $translation; | ||
} | ||
} | ||
} | ||
|
||
fclose($fileHandler); | ||
} | ||
|
||
/** | ||
* Sets locale information, according to one from the header row of the source csv | ||
* Set it to false for enabling the "no translation mode" | ||
* <code> | ||
* // Set locale to Dutch | ||
* $adapter->setLocale('nl_NL'); | ||
* </code> | ||
*/ | ||
public function setLocale($locale) | ||
{ | ||
if ($locale !== false && !array_key_exists($locale, $this->_translate)) { | ||
throw new Exception("The locale '{$locale}' is not available in the data source."); | ||
return false; | ||
} else { | ||
return $this->locale = $locale; | ||
} | ||
} | ||
|
||
/** | ||
* Returns the translation related to the given key and the previsouly set locale | ||
*/ | ||
public function query($index, $placeholders = null) | ||
{ | ||
if (!$this->exists($index)) { | ||
throw new Exception("They key '{$index}' was not found."); | ||
} | ||
|
||
if ($this->locale === false) { | ||
// "no translation mode" | ||
$translation = $index; | ||
} else { | ||
$translation = $this->_translate[$this->locale][$index]; | ||
} | ||
|
||
return $this->replacePlaceholders($translation, $placeholders); | ||
} | ||
|
||
/** | ||
* Check whether is defined a translation key in the internal array | ||
*/ | ||
public function exists($index) | ||
{ | ||
if (is_null($this->locale)) { | ||
throw new Exception('The locale must have been defined.'); | ||
} | ||
return in_array($index, $this->getIndexes()); | ||
} | ||
|
||
/** | ||
* Returns all the translation keys | ||
*/ | ||
public function getIndexes() | ||
{ | ||
return $this->indexes; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
;en_US;fr_FR;es_ES | ||
label_street;street;rue;calle | ||
label_car;car;voiture;coche | ||
label_home;home;maison;casa |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
namespace Phalcon\Test\Unit\Translate\Adapter\CsvMulti; | ||
|
||
use Phalcon\Translate\Adapter\CsvMulti; | ||
|
||
/** | ||
* Class GetIndexesCest | ||
*/ | ||
abstract class Base | ||
{ | ||
|
||
protected $adapter; | ||
|
||
public function _before() | ||
{ | ||
$content = dirname(__FILE__) . '/../../../../_data/assets/translation/csv/names.csv'; | ||
$params = ['content' => $content]; | ||
$this->adapter = new CsvMulti($params); | ||
} | ||
|
||
public function _after() | ||
{ | ||
$this->adapter = null; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
namespace Phalcon\Test\Unit\Translate\Adapter\CsvMulti; | ||
|
||
// TODO : autoload instead of require_once ? see https://stackoverflow.com/questions/35386276/codeception-cest-inheritance | ||
require_once 'Base.php'; | ||
use Phalcon\Test\Unit\Translate\Adapter\CsvMulti\Base; | ||
|
||
use Phalcon\Translate\Exception; | ||
use UnitTester; | ||
|
||
/** | ||
* Class ExistsCest | ||
*/ | ||
class ExistsCest extends Base | ||
{ | ||
public function translateAdapterExistsNoLocaleSet(UnitTester $I) | ||
{ | ||
$I->wantToTest('Translate\Adapter\CsvMulti - exists cannot work without a locale having been set'); | ||
$I->expectThrowable( | ||
new Exception('The locale must have been defined.'), | ||
function () { | ||
$this->adapter->exists('label_street'); | ||
} | ||
); | ||
} | ||
|
||
public function translateAdapterExistsItDoesnt(UnitTester $I) | ||
{ | ||
$I->wantToTest('Translate\Adapter\CsvMulti - exists returns false'); | ||
$this->adapter->setLocale('en_US'); | ||
$I->assertFalse($this->adapter->exists('label_cat')); | ||
} | ||
|
||
public function translateAdapterExistsItDoes(UnitTester $I) | ||
{ | ||
$I->wantToTest('Translate\Adapter\CsvMulti - exists returns true'); | ||
$this->adapter->setLocale('en_US'); | ||
$I->assertTrue($this->adapter->exists('label_street')); | ||
$I->assertTrue($this->adapter->exists('label_car')); | ||
$I->assertTrue($this->adapter->exists('label_home')); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace Phalcon\Test\Unit\Translate\Adapter\CsvMulti; | ||
|
||
// TODO : autoload instead of require_once ? see https://stackoverflow.com/questions/35386276/codeception-cest-inheritance | ||
require_once 'Base.php'; | ||
use Phalcon\Test\Unit\Translate\Adapter\CsvMulti\Base; | ||
|
||
use UnitTester; | ||
|
||
/** | ||
* Class GetIndexesCest | ||
*/ | ||
class GetIndexesCest extends Base | ||
{ | ||
public function getIndexes(UnitTester $I) | ||
{ | ||
$I->wantToTest('Translate\Adapter\CsvMulti - getIndexes returns the indexes'); | ||
$this->adapter->setLocale('en_US'); | ||
$I->assertEquals(['label_street', 'label_car', 'label_home'], $this->adapter->getIndexes()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<?php | ||
|
||
namespace Phalcon\Test\Unit\Translate\Adapter\CsvMulti; | ||
|
||
// TODO : autoload instead of require_once ? see https://stackoverflow.com/questions/35386276/codeception-cest-inheritance | ||
require_once 'Base.php'; | ||
use Phalcon\Test\Unit\Translate\Adapter\CsvMulti\Base; | ||
|
||
use Phalcon\Translate\Exception; | ||
use UnitTester; | ||
|
||
/** | ||
* Class QueryCest | ||
*/ | ||
class QueryCest extends Base | ||
{ | ||
|
||
public function queryNoTranslationMode(UnitTester $I) | ||
{ | ||
$I->wantToTest('Translate\Adapter\CsvMulti - query returns the key when locale is false'); | ||
$this->adapter->setLocale(false); | ||
$I->assertEquals('label_street', $this->adapter->query('label_street')); | ||
$I->assertEquals('label_street', $this->adapter->query('label_street', 'placeholder_for_street')); | ||
} | ||
|
||
public function queryDoesTranslate(UnitTester $I) | ||
{ | ||
$I->wantToTest('Translate\Adapter\CsvMulti - query returns the translated string matching the index'); | ||
$this->adapter->setLocale('en_US'); | ||
$I->assertEquals('street', $this->adapter->query('label_street')); | ||
$I->assertEquals('car', $this->adapter->query('label_car')); | ||
$I->assertEquals('home', $this->adapter->query('label_home')); | ||
$this->adapter->setLocale('fr_FR'); | ||
$I->assertEquals('rue', $this->adapter->query('label_street')); | ||
$I->assertEquals('voiture', $this->adapter->query('label_car')); | ||
$I->assertEquals('maison', $this->adapter->query('label_home')); | ||
$this->adapter->setLocale('es_ES'); | ||
$I->assertEquals('calle', $this->adapter->query('label_street')); | ||
$I->assertEquals('coche', $this->adapter->query('label_car')); | ||
$I->assertEquals('casa', $this->adapter->query('label_home')); | ||
} | ||
|
||
public function queryKeyDoesntExist(UnitTester $I) | ||
{ | ||
$I->wantToTest('Translate\Adapter\CsvMulti - query raises an exception when the key doesn\'t match'); | ||
$I->expectThrowable( | ||
new Exception("They key 'label_unexists' was not found."), | ||
function () { | ||
$this->adapter->setLocale('en_US'); | ||
$this->adapter->query('label_unexists'); | ||
} | ||
); | ||
} | ||
} |