diff --git a/composer.json b/composer.json index 107528ad..e3b29d43 100644 --- a/composer.json +++ b/composer.json @@ -61,11 +61,13 @@ "nette/utils": "~2.3@dev", "latte/latte": "~2.3@dev", "tracy/tracy": "~2.3@dev", + + "kdyby/doctrine": "~2.3", + "kdyby/events": "~2.3.1", "symfony/console": "~2.3", + "nette/tester": "~1.4", - "mockery/mockery": "~0.9", - "kdyby/doctrine": "~2.3", - "kdyby/events": "~2.3.1" + "mockery/mockery": "~0.9" }, "autoload": { "psr-0": { diff --git a/docs/en/index.md b/docs/en/index.md index 9089a33e..a1630690 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -250,7 +250,7 @@ You can also use your own Loader, then you put to your config.neon full name wit ```yml translation: database: - loader: \Namespace\CustomLoader + loader: Namespace\CustomLoader ``` The loader needs to implement the [Symfony\Component\Translation\Loader\LoaderInterface](https://github.com/symfony/Translation/blob/3ba54181c8386b180999d942bf33681a726bb70f/Loader/LoaderInterface.php) diff --git a/src/Kdyby/Translation/Console/CreateTableCommand.php b/src/Kdyby/Translation/Console/CreateTableCommand.php index 41191cb4..cc66733a 100644 --- a/src/Kdyby/Translation/Console/CreateTableCommand.php +++ b/src/Kdyby/Translation/Console/CreateTableCommand.php @@ -10,12 +10,12 @@ namespace Kdyby\Translation\Console; -use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Types\Type; use Kdyby; +use Kdyby\Console\ContainerHelper; use Nette; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\Helper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -23,90 +23,61 @@ /** - * @author Filip Procházka + * @author Azathoth + * + * @method ContainerHelper|Helper getHelper(string $name) */ class CreateTableCommand extends Command { - /** @var Nette\DI\Container */ - private $serviceLocator; - - /** @var Connection */ - private $connection; - - /** @var AbstractSchemaManager */ - private $schemaManager; - - /** @var string */ - public $table; - - /** @var string */ - public $key; - - /** @var string */ - public $locale; + /** + * @var Kdyby\Translation\Loader\IDatabaseLoader + */ + private $databaseLoader; - /** @var string */ - public $message; - /** @var string */ - public $updatedAt; protected function configure() { - $this->setName('kdyby:translation-create-table') + $this->setName('kdyby:translation:create-table') ->setDescription('Builds query for creating of database table.') - ->setDefinition(array( - new InputOption( - 'dump-sql', NULL, InputOption::VALUE_NONE, - 'Dumps the generated SQL statement to the screen (does not execute it).' - ), - new InputOption( - 'force', NULL, InputOption::VALUE_NONE, - 'Causes the generated SQL statement to be physically executed against your database.' - ) - )); + ->addOption('dump-sql', NULL, InputOption::VALUE_NONE, 'Dumps the generated SQL statement to the screen (does not execute it).') + ->addOption('force', NULL, InputOption::VALUE_NONE, 'Causes the generated SQL statement to be physically executed against your database.'); } + protected function initialize(InputInterface $input, OutputInterface $output) { - $this->serviceLocator = $this->getHelper('container')->getContainer(); - $this->connection = $this->serviceLocator->getByType('Doctrine\DBAL\Connection'); - $this->schemaManager = $this->serviceLocator->getByType('Doctrine\DBAL\Schema\AbstractSchemaManager'); + $serviceLocator = $this->getHelper('container')->getContainer(); + $this->databaseLoader = $serviceLocator->getByType('Kdyby\Translation\Loader\IDatabaseLoader'); } + protected function execute(InputInterface $input, OutputInterface $output) { if (!$input->getOption('dump-sql') && !$input->getOption('force')) { $output->writeln('You must run the command either with --dump-sql or --force.'); - return; + return 1; } - if ($this->schemaManager->tablesExist($this->table)) { - $output->writeln('Table already exists.'); - return; - } + try { + $queries = $this->databaseLoader->setupDatabase($input->getOption('force')); - $table = $this->schemaManager->createSchema() - ->createTable($this->table); - $table->addColumn($this->key, Type::STRING); - $table->addColumn($this->locale, Type::STRING); - $table->addColumn($this->message, Type::TEXT); - $table->addColumn($this->updatedAt, Type::DATETIME); - $table->setPrimaryKey(array($this->key, $this->locale)); - $table->addIndex(array($this->updatedAt)); - - if ($input->getOption('dump-sql')) { - list($sql) = $this->connection->getDatabasePlatform()->getCreateTableSQL($table); - $output->writeln('Create table SQL:'); - $output->writeln($sql); - } + if ($input->getOption('force')) { + $output->writeln(sprintf('Database schema updated successfully! Translation table created.')); + } + + if ($input->getOption('dump-sql')) { + $output->writeln(implode(";\n", $queries)); + } + + return 0; - if ($input->getOption('force')) { - $this->schemaManager->createTable($table); - $output->writeln(sprintf('Database schema updated successfully! Translation table created.')); + } catch (Kdyby\Translation\DatabaseException $e) { + $this->getApplication()->renderException($e, $output); + return 1; } } diff --git a/src/Kdyby/Translation/DI/Configuration.php b/src/Kdyby/Translation/DI/Configuration.php new file mode 100644 index 00000000..31766833 --- /dev/null +++ b/src/Kdyby/Translation/DI/Configuration.php @@ -0,0 +1,125 @@ + + */ +class Configuration +{ + + /** + * @var string + */ + private $table = 'translations'; + + /** + * @var string + */ + private $key = 'key'; + + /** + * @var string + */ + private $locale = 'locale'; + + /** + * @var string + */ + private $message = 'message'; + + /** + * @var string + */ + private $updatedAt = 'updated_at'; + + + + /** + * @param string $table + */ + public function setTableName($table) + { + $this->table = $table; + } + + + + /** + * @return string + */ + public function getTableName() + { + return $this->table; + } + + + + /** + * @param string $key + * @param string $locale + * @param string $message + * @param string $updatedAt + */ + public function setColumnNames($key, $locale, $message, $updatedAt) + { + $this->key = $key; + $this->locale = $locale; + $this->message = $message; + $this->updatedAt = $updatedAt; + } + + + + /** + * @return string + */ + public function getKeyColumn() + { + return $this->key; + } + + + + /** + * @return string + */ + public function getLocaleColumn() + { + return $this->locale; + } + + + + /** + * @return string + */ + public function getMessageColumn() + { + return $this->message; + } + + + + /** + * @return string + */ + public function getUpdatedAtColumn() + { + return $this->updatedAt; + } + +} diff --git a/src/Kdyby/Translation/DI/TranslationExtension.php b/src/Kdyby/Translation/DI/TranslationExtension.php index df217cfa..3504b772 100644 --- a/src/Kdyby/Translation/DI/TranslationExtension.php +++ b/src/Kdyby/Translation/DI/TranslationExtension.php @@ -12,6 +12,7 @@ use Kdyby; use Kdyby\Translation\InvalidResourceException; +use Kdyby\Translation\Resource\DatabaseResource; use Nette; use Nette\DI\Statement; use Nette\PhpGenerator as Code; @@ -61,7 +62,7 @@ class TranslationExtension extends Nette\DI\CompilerExtension 'key' => 'key', 'locale' => 'locale', 'message' => 'message', - 'updatedAt' => 'updated_at' + 'updatedAt' => 'updated_at', ], 'loader' => NULL, 'dumper' => NULL, @@ -73,16 +74,24 @@ class TranslationExtension extends Nette\DI\CompilerExtension */ private $loaders; + /** + * @var array + */ public static $dbLoaders = array( - Kdyby\Translation\Resource\DatabaseResource::NETTE_DB => 'Kdyby\Translation\Loader\NetteDbLoader', - Kdyby\Translation\Resource\DatabaseResource::DOCTRINE => 'Kdyby\Translation\Loader\DoctrineLoader' + DatabaseResource::NETTE_DB => 'Kdyby\Translation\Loader\NetteDbLoader', + DatabaseResource::DOCTRINE => 'Kdyby\Translation\Loader\DoctrineLoader', ); + /** + * @var array + */ public static $dbDumpers = array( - Kdyby\Translation\Resource\DatabaseResource::NETTE_DB => 'Kdyby\Translation\Dumper\NetteDbDumper', - Kdyby\Translation\Resource\DatabaseResource::DOCTRINE => 'Kdyby\Translation\Dumper\DoctrineDumper' + DatabaseResource::NETTE_DB => 'Kdyby\Translation\Dumper\NetteDbDumper', + DatabaseResource::DOCTRINE => 'Kdyby\Translation\Dumper\DoctrineDumper', ); + + public function __construct() { $this->defaults['cache'] = new Statement($this->defaults['cache'], array('%tempDir%/cache')); @@ -96,6 +105,9 @@ public function loadConfiguration() $builder = $this->getContainerBuilder(); $config = $this->getConfig(); + if (empty($config['database']['dumper'])) { + $config['database']['dumper'] = $config['database']['loader']; + } $translator = $builder->addDefinition($this->prefix('default')) ->setClass('Kdyby\Translation\Translator', array($this->prefix('@userLocaleResolver'))) @@ -149,22 +161,19 @@ public function loadConfiguration() ->setClass('Symfony\Component\Translation\Writer\TranslationWriter') ->setInject(FALSE); - $this->loadDumpers(); + $this->loadDumpers($config); $builder->addDefinition($this->prefix('loader')) ->setClass('Kdyby\Translation\TranslationLoader') ->setInject(FALSE); - $this->loadLoaders(); + $this->loadLoaders($config); if ($this->isRegisteredConsoleExtension()) { $this->loadConsole($config); } - foreach ($builder->findByTag(self::DATABASE_LOADER_TAG) as $dbLoader => $true) { - $translator->addSetup('?->addResources(?)', array('@'.$dbLoader, '@self')); - } - + $this->loadConfigService($config['database']); } @@ -215,6 +224,19 @@ protected function loadLocaleResolver(array $config) + protected function loadConfigService(array $config) + { + $builder = $this->getContainerBuilder(); + + $columns = $config['columns']; + $builder->addDefinition($this->prefix('configuration')) + ->setClass('Kdyby\Translation\DI\Configuration') + ->addSetup('setTableName', array($config['table'])) + ->addSetup('setColumnNames', array($columns['key'], $columns['locale'], $columns['message'], $columns['updatedAt'])); + } + + + protected function loadConsole(array $config) { $builder = $this->getContainerBuilder(); @@ -226,26 +248,17 @@ protected function loadConsole(array $config) ->setInject(FALSE) ->addTag('kdyby.console.command', 'latte'); - - $database = $config['database']; $builder->addDefinition($this->prefix('console.initDatabase')) ->setClass('Kdyby\Translation\Console\CreateTableCommand') - ->addSetup('$table', array($database['table'])) - ->addSetup('$key', array($database['columns']['key'])) - ->addSetup('$locale', array($database['columns']['locale'])) - ->addSetup('$message', array($database['columns']['message'])) - ->addSetup('$updatedAt', array($database['columns']['updatedAt'])) ->setInject(FALSE) ->addTag('kdyby.console.command', 'database'); - } - protected function loadDumpers() + protected function loadDumpers(array $config) { $builder = $this->getContainerBuilder(); - $config = $this->getConfig(); foreach ($this->loadFromFile(__DIR__ . '/config/dumpers.neon') as $format => $class) { $builder->addDefinition($this->prefix('dumper.' . $format)) @@ -253,38 +266,19 @@ protected function loadDumpers() ->addTag(self::DUMPER_TAG, $format); } - $dumper = $config['database']['dumper']; - $isDumper = FALSE; - if ($dumper !== NULL) { - $isDumper = TRUE; - } else { - $loader = $config['database']['loader']; - if (in_array($loader, array_keys(self::$dbLoaders))) { //if you register doctrine of nettedb loader, dumper is also registered - $isDumper = TRUE; - $dumper = $loader; - } - } - if ($isDumper) { - if (in_array($dumper, array_keys(self::$dbDumpers))) { - $class = self::$dbDumpers[$dumper]; - } else { - $class = $dumper; - } - $columns = $config['database']['columns']; + if (($driver = $config['database']['dumper']) !== NULL) { $service = $builder->addDefinition($this->prefix('dumper.database')); - Nette\DI\Compiler::parseService($service, $class); - $service->addTag(self::DUMPER_TAG, 'database') - ->addSetup('setTableName', array($config['database']['table'])) - ->addSetup('setColumnNames', array($columns['key'], $columns['locale'], $columns['message'], $columns['updatedAt'])); + $definition = (is_string($driver) && isset(self::$dbDumpers[$driver])) ? self::$dbDumpers[$driver] : $driver; + Nette\DI\Compiler::parseService($service, $definition); + $service->addTag(self::DUMPER_TAG, 'database'); } } - protected function loadLoaders() + protected function loadLoaders(array $config) { $builder = $this->getContainerBuilder(); - $config = $this->getConfig(); foreach ($this->loadFromFile(__DIR__ . '/config/loaders.neon') as $format => $class) { $builder->addDefinition($this->prefix('loader.' . $format)) @@ -292,26 +286,19 @@ protected function loadLoaders() ->addTag(self::LOADER_TAG, $format); } - $loader = $config['database']['loader']; - if ($loader !== NULL) { - if (in_array($loader, array_keys(self::$dbLoaders))) { - $class = self::$dbLoaders[$loader]; - } else { - $class = $loader; - } - $columns = $config['database']['columns']; + if (($driver = $config['database']['loader']) !== NULL) { $service = $builder->addDefinition($this->prefix('loader.database')); - Nette\DI\Compiler::parseService($service, $class); - $service->addTag(self::LOADER_TAG, 'database') - ->addTag(self::DATABASE_LOADER_TAG, $loader) - ->addSetup('setTableName', array($config['database']['table'])) - ->addSetup('setColumnNames', array($columns['key'], $columns['locale'], $columns['message'], $columns['updatedAt'])); - + $definition = (is_string($driver) && isset(self::$dbLoaders[$driver])) ? self::$dbLoaders[$driver] : $driver; + Nette\DI\Compiler::parseService($service, $definition); + $service + ->setClass('Kdyby\Translation\Loader\IDatabaseLoader') + ->addTag(self::LOADER_TAG, 'database') + ->addTag(self::DATABASE_LOADER_TAG, $driver); } - } + protected function loadExtractors() { $builder = $this->getContainerBuilder(); @@ -357,6 +344,11 @@ public function beforeCompile() ->addSetup('$service->onRequest[] = ?', array(array($this->prefix('@panel'), 'onRequest'))); } + $translator = $builder->getDefinition($this->prefix('default')); + foreach ($builder->findByTag(self::DATABASE_LOADER_TAG) as $dbLoader => $true) { + $translator->addSetup('?->addResources(?)', array('@' . $dbLoader, '@self')); + } + Kdyby\Translation\Diagnostics\Panel::registerBluescreen(); $extractor = $builder->getDefinition($this->prefix('extractor')); @@ -401,16 +393,15 @@ public function beforeCompile() $builder->addDependency($dir); } - $this->loadResourcesFromDirs($dirs); + $this->loadResourcesFromDirs($dirs, $config); } } - protected function loadResourcesFromDirs($dirs) + protected function loadResourcesFromDirs($dirs, array $config) { $builder = $this->getContainerBuilder(); - $config = $this->getConfig(); $whitelistRegexp = Kdyby\Translation\Translator::buildWhitelistRegexp($config['whitelist']); $translator = $builder->getDefinition($this->prefix('default')); diff --git a/src/Kdyby/Translation/Dumper/DatabaseDumper.php b/src/Kdyby/Translation/Dumper/DatabaseDumper.php index 5459ec79..59277f0d 100644 --- a/src/Kdyby/Translation/Dumper/DatabaseDumper.php +++ b/src/Kdyby/Translation/Dumper/DatabaseDumper.php @@ -1,50 +1,41 @@ + */ +abstract class DatabaseDumper implements DumperInterface +{ - /** @var string */ - protected $locale = 'locale'; + /** + * @var Configuration + */ + protected $config; - /** @var string */ - protected $message = 'message'; - /** @var string */ - protected $updatedAt = 'updated_at'; - /** - * @param string $table - */ - public function setTableName($table) + public function __construct(Configuration $config) { - $this->table = $table; + $this->config = $config; } - /** - * @param string $key - * @param string $locale - * @param string $message - * @param string $updatedAt - */ - public function setColumnNames($key, $locale, $message, $updatedAt) - { - $this->key = $key; - $this->locale = $locale; - $this->message = $message; - $this->updatedAt = $updatedAt; - } + /** * Dumps the message catalogue. @@ -55,7 +46,7 @@ public function setColumnNames($key, $locale, $message, $updatedAt) public function dump(MessageCatalogue $messages, $options = array()) { $messagesArray = $messages->all(); - if (isset($messagesArray[NULL]) && is_array($messagesArray[NULL])) { //bugfix for translations without domain + if (isset($messagesArray[NULL]) && is_array($messagesArray[NULL])) { //hack for translations without domain $messagesArray += $messagesArray[NULL]; unset($messagesArray[NULL]); } @@ -76,22 +67,35 @@ public function dump(MessageCatalogue $messages, $options = array()) } } $this->commit(); - } catch(\Exception $e) { + + } catch (\Exception $e) { $this->rollBack(); throw $e; } } + + abstract protected function getExistingKeys($keys, $locale); + + abstract protected function beginTransaction(); + + abstract protected function commit(); + + abstract protected function rollBack(); + + abstract protected function insert($key, $locale, $message); + + abstract protected function update($key, $locale, $message); } diff --git a/src/Kdyby/Translation/Dumper/DoctrineDumper.php b/src/Kdyby/Translation/Dumper/DoctrineDumper.php index 0a9d6ec1..b333ac60 100644 --- a/src/Kdyby/Translation/Dumper/DoctrineDumper.php +++ b/src/Kdyby/Translation/Dumper/DoctrineDumper.php @@ -1,105 +1,139 @@ + */ class DoctrineDumper extends DatabaseDumper { - /** @var Connection */ - private $connection; - /** - * @param Connection $conn + * @var Connection */ - public function __construct(Connection $conn) + private $db; + + + + public function __construct(Connection $db, Configuration $config) { - $this->connection = $conn; + parent::__construct($config); + $this->db = $db; } + + protected function getExistingKeys($keys, $locale) { - if( !function_exists( 'array_column' ) ) { //just because of PHP 5.4, where function array_column is not present. Fuck you, PHP 5.4 - function array_column( array $input, $column_key, $index_key = NULL ) { - $result = array(); - foreach( $input as $k => $v ) - $result[ $index_key ? $v[ $index_key ] : $k ] = $v[ $column_key ]; - return $result; - } - } + try { + $qb = $this->db->createQueryBuilder() + ->addSelect($this->db->quoteIdentifier($this->config->getKeyColumn()) . ' AS ' . $this->db->quoteIdentifier('key')) + ->from($this->db->quoteIdentifier($this->config->getTableName())) + ->andWhere($this->db->quoteIdentifier($this->config->getLocaleColumn()) . ' = :locale') + ->andWhere($this->db->quoteIdentifier($this->config->getKeyColumn()) . ' IN (:keys)') + ->setParameter('locale', $locale) + ->setParameter('keys', $keys, Connection::PARAM_STR_ARRAY); - $qb = $this->connection->createQueryBuilder() - ->addSelect($this->connection->quoteIdentifier($this->key).' AS '.$this->connection->quoteIdentifier('key')) - ->from($this->connection->quoteIdentifier($this->table)) - ->andWhere($this->connection->quoteIdentifier($this->locale).' = :locale') - ->andWhere($this->connection->quoteIdentifier($this->key).' IN (:keys)') - ->setParameter('locale', $locale) - ->setParameter('keys', $keys, Connection::PARAM_STR_ARRAY); - $stmt = $qb->execute(); - return array_column($stmt->fetchAll(), 'key'); //to get only one dimensional array of keys + return Helpers::arrayColumn($qb->execute()->fetchAll(), 'key'); //to get only one dimensional array of keys + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } } - protected function beginTransaction() - { - $this->connection->beginTransaction(); - } - protected function commit() - { - $this->connection->commit(); - } protected function insert($key, $locale, $message) { - $qb = $this->connection->createQueryBuilder(); - $qb->insert($this->table) - ->values([ - $this->connection->quoteIdentifier($this->key) => ":key", - $this->connection->quoteIdentifier($this->locale) => ":locale", - $this->connection->quoteIdentifier($this->message) => ":message", - $this->connection->quoteIdentifier($this->updatedAt) => ":updatedAt" - ]) - ->setParameters([ + try { + $qb = $this->db->createQueryBuilder(); + $qb->insert($this->db->quoteIdentifier($this->config->getTableName())) + ->values([ + $this->db->quoteIdentifier($this->config->getKeyColumn()) => ":key", + $this->db->quoteIdentifier($this->config->getLocaleColumn()) => ":locale", + $this->db->quoteIdentifier($this->config->getMessageColumn()) => ":message", + $this->db->quoteIdentifier($this->config->getUpdatedAtColumn()) => ":updatedAt", + ]); + + $qb->setParameters([ 'key' => $key, 'locale' => $locale, 'message' => $message, - 'updatedAt' => new \DateTime() + 'updatedAt' => new \DateTime(), ], [ - 'key' => Type::STRING, - 'locale' => Type::STRING, - 'message' => Type::STRING, - 'updatedAt' => Type::DATETIME + 'updatedAt' => Type::DATETIME, ]); - $qb->execute(); + + $qb->execute(); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } } + + protected function update($key, $locale, $message) { - $qb = $this->connection->createQueryBuilder(); - $qb->update($this->connection->quoteIdentifier($this->table)) - ->set($this->connection->quoteIdentifier($this->message), ':message') - ->set($this->connection->quoteIdentifier($this->updatedAt), ':updatedAt') - ->andWhere($this->connection->quoteIdentifier($this->key).' = :key') - ->andWhere($this->connection->quoteIdentifier($this->locale).' = :locale') - ->setParameters([ + try { + $qb = $this->db->createQueryBuilder(); + $qb->update($this->db->quoteIdentifier($this->config->getTableName())) + ->set($this->db->quoteIdentifier($this->config->getMessageColumn()), ':message') + ->set($this->db->quoteIdentifier($this->config->getUpdatedAtColumn()), ':updatedAt') + ->andWhere($this->db->quoteIdentifier($this->config->getKeyColumn()) . ' = :key') + ->andWhere($this->db->quoteIdentifier($this->config->getLocaleColumn()) . ' = :locale'); + + $qb->setParameters([ 'key' => $key, 'locale' => $locale, 'message' => $message, - 'updatedAt' => new \DateTime() + 'updatedAt' => new \DateTime(), ], [ - 'key' => Type::STRING, - 'locale' => Type::STRING, - 'message' => Type::STRING, - 'updatedAt' => Type::DATETIME + 'updatedAt' => Type::DATETIME, ]); - $qb->execute(); + + $qb->execute(); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } + } + + + + protected function beginTransaction() + { + $this->db->beginTransaction(); + } + + + + protected function commit() + { + $this->db->commit(); } + + protected function rollBack() { - $this->connection->rollBack(); + $this->db->rollBack(); } } diff --git a/src/Kdyby/Translation/Dumper/NetteDbDumper.php b/src/Kdyby/Translation/Dumper/NetteDbDumper.php index 6ae33b89..4eb16e4a 100644 --- a/src/Kdyby/Translation/Dumper/NetteDbDumper.php +++ b/src/Kdyby/Translation/Dumper/NetteDbDumper.php @@ -1,70 +1,115 @@ + */ class NetteDbDumper extends DatabaseDumper { - /** @var Context */ - private $db; - /** - * @param Context $db + * @var Context */ - public function __construct(Context $db) + private $db; + + + + public function __construct(Context $db, Configuration $config) { + parent::__construct($config); $this->db = $db; } + protected function getExistingKeys($keys, $locale) { - return $this->db->table($this->table) - ->select($this->delimite($this->key).' AS '.$this->delimite('key')) - ->where($this->delimite($this->locale).' = ?', $locale) - ->where($this->delimite($this->key).' IN (?)', $keys) - ->fetchPairs('key', 'key'); //to get only one dimensional array of keys + try { + return $this->db->table($this->config->getTableName()) + ->select($this->delimite($this->config->getKeyColumn()) . ' AS ' . $this->delimite('key')) + ->where($this->delimite($this->config->getLocaleColumn()) . ' = ?', $locale) + ->where($this->delimite($this->config->getKeyColumn()) . ' IN (?)', $keys) + ->fetchPairs('key', 'key'); //to get only one dimensional array of keys + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } } - protected function beginTransaction() + + + protected function insert($key, $locale, $message) { - $this->db->beginTransaction(); + try { + $this->db->table($this->config->getTableName())->insert([ + $this->config->getKeyColumn() => $key, + $this->config->getLocaleColumn() => $locale, + $this->config->getMessageColumn() => $message, + $this->config->getUpdatedAtColumn() => new \DateTime(), + ]); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } } - protected function commit() + + + protected function update($key, $locale, $message) { - $this->db->commit(); + try { + $this->db->table($this->config->getTableName()) + ->where($this->config->getKeyColumn() . " = ?", $key) + ->where($this->config->getLocaleColumn() . " = ?", $locale) + ->update([ + $this->config->getMessageColumn() => $message, + $this->config->getUpdatedAtColumn() => new \DateTime(), + ]); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } } - protected function insert($key, $locale, $message) + + + protected function beginTransaction() { - $this->db->table($this->table) - ->insert([ - $this->key => $key, - $this->locale => $locale, - $this->message => $message, - $this->updatedAt => new \DateTime() - ]); + $this->db->beginTransaction(); } - protected function update($key, $locale, $message) + + + protected function commit() { - $this->db->table($this->table) - ->where("$this->key = ?", $key) - ->where("$this->locale = ?", $locale) - ->update([ - $this->message => $message, - $this->updatedAt => new \DateTime() - ]); + $this->db->commit(); } + + protected function rollBack() { $this->db->rollBack(); } + + private function delimite($name) { return $this->db->getConnection()->getSupplementalDriver()->delimite($name); diff --git a/src/Kdyby/Translation/Helpers.php b/src/Kdyby/Translation/Helpers.php index 9691cc5d..5eab9e68 100644 --- a/src/Kdyby/Translation/Helpers.php +++ b/src/Kdyby/Translation/Helpers.php @@ -1,31 +1,74 @@ + */ class Helpers { - public static function flatten(array &$messages, array $subnode = NULL, $path = NULL) - { - if (NULL === $subnode) { - $subnode = &$messages; - } - foreach ($subnode as $key => $value) { - if (is_array($value)) { - $nodePath = $path ? $path.'.'.$key : $key; - static::flatten($messages, $value, $nodePath); - if (NULL === $path) { - unset($messages[$key]); - } - } elseif (NULL !== $path) { - $messages[$path.'.'.$key] = $value; - } - } - } + public static function flatten(array &$messages, array $subNode = NULL, $path = NULL) + { + if (NULL === $subNode) { + $subNode = &$messages; + } + + foreach ($subNode as $key => $value) { + if (is_array($value)) { + $nodePath = $path ? $path . '.' . $key : $key; + static::flatten($messages, $value, $nodePath); + if ($path === NULL) { + unset($messages[$key]); + } + + } elseif ($path !== NULL) { + $messages[$path . '.' . $key] = $value; + } + } + } + + + + /** + * @internal just because of PHP 5.4, where function array_column is not present. Fuck you, PHP 5.4 + * @param array $input + * @param string $columnKey + * @param string $indexKey + * @return array + */ + public static function arrayColumn(array $input, $columnKey, $indexKey = NULL) + { + $result = array(); + foreach ($input as $k => $v) { + $result[$indexKey ? $v[$indexKey] : $k] = $v[$columnKey]; + } + return $result; + } + + + + /** + * @param string $message + * @return array [domain, message] + */ + public static function extractMessageDomain($message) + { + if (strpos($message, '.') !== FALSE && strpos($message, ' ') === FALSE) { + list($domain, $message) = explode('.', $message, 2); + } else { + $domain = 'messages'; + } + return array($domain, $message); + } } diff --git a/src/Kdyby/Translation/Loader/DatabaseLoader.php b/src/Kdyby/Translation/Loader/DatabaseLoader.php index 8fe0c3b1..c72e475d 100644 --- a/src/Kdyby/Translation/Loader/DatabaseLoader.php +++ b/src/Kdyby/Translation/Loader/DatabaseLoader.php @@ -1,77 +1,58 @@ + */ +abstract class DatabaseLoader implements IDatabaseLoader +{ - /** @var string */ - protected $locale = 'locale'; + /** + * @var Configuration + */ + protected $config; - /** @var string */ - protected $message = 'message'; - /** @var string */ - protected $updatedAt = 'updated_at'; - /** - * @param string $table - * @return $this - */ - public function setTableName($table) + public function __construct(Configuration $config) { - $this->table = $table; - return $this; + $this->config = $config; } + + /** - * @param string $key - * @param string $locale - * @param string $message - * @param string $updatedAt - * @return $this + * {@inheritdoc} */ - public function setColumnNames($key, $locale, $message, $updatedAt) - { - $this->key = $key; - $this->locale = $locale; - $this->message = $message; - $this->updatedAt = $updatedAt; - return $this; - } - public function load($resource, $locale, $domain = NULL) { $catalogue = new MessageCatalogue($locale); $translations = $this->getTranslations($locale); - foreach($translations as $translation) { - if ($domain === NULL) { - $key = $translation['key']; - if (Strings::contains($key, '.')) { - if (function_exists('mb_strpos')) { - $prefix = Strings::substring($key, 0, mb_strpos($key, '.')); - } else { - $prefix = Strings::substring($key, 0, strpos($key, '.')); - } - $key = Strings::substring($key, Strings::length($prefix) + 1); //plus one because of dot - } else { - $prefix = $domain; - } - $catalogue->set($key, $translation['message'], $prefix); - } else { + foreach ($translations as $translation) { + if ($domain !== NULL) { $catalogue->set($translation['key'], $translation['message'], $domain); + + } else { + list($prefix, $key) = Helpers::extractMessageDomain($translation['key']); + $catalogue->set($key, $translation['message'], $prefix); } } @@ -80,17 +61,11 @@ public function load($resource, $locale, $domain = NULL) return $catalogue; } - /** - * @return array - */ - abstract public function getLocales(); + /** - * @param $locale - * @return \DateTime + * @inheritdoc */ - abstract protected function getLastUpdate($locale); - public function addResources(Translator $translator) { foreach ($this->getLocales() as $locale) { @@ -98,7 +73,27 @@ public function addResources(Translator $translator) } } + + + /** + * @param $locale + * @return \DateTime + */ + abstract protected function getLastUpdate($locale); + + + + /** + * @return string + */ abstract protected function getResourceName(); + + + /** + * @param string $locale + * @return array + */ abstract protected function getTranslations($locale); + } diff --git a/src/Kdyby/Translation/Loader/DoctrineLoader.php b/src/Kdyby/Translation/Loader/DoctrineLoader.php index e75fd58f..4db22ccc 100644 --- a/src/Kdyby/Translation/Loader/DoctrineLoader.php +++ b/src/Kdyby/Translation/Loader/DoctrineLoader.php @@ -1,89 +1,154 @@ + */ class DoctrineLoader extends DatabaseLoader { - /** @var Connection */ - private $conn; - /** - * @param Connection $conn + * @var Connection */ - public function __construct(Connection $conn) + private $db; + + + + public function __construct(Connection $conn, Configuration $config) { - $this->conn = $conn; + parent::__construct($config); + $this->db = $conn; } + + /** * @return array */ public function getLocales() { - if( !function_exists( 'array_column' ) ) { //just because of PHP 5.4, where function array_column is not present. Fuck you, PHP 5.4 - function array_column( array $input, $column_key, $index_key = NULL ) { - $result = array(); - foreach( $input as $k => $v ) - $result[ $index_key ? $v[ $index_key ] : $k ] = $v[ $column_key ]; - return $result; - } - } - - $qb = $this->conn->createQueryBuilder() - ->addSelect('DISTINCT '.$this->conn->quoteIdentifier($this->locale).' AS locale') - ->from($this->conn->quoteIdentifier($this->table)); try { - $stmt = $qb->execute(); - $locales = array_column($stmt->fetchAll(), 'locale'); - } catch(TableNotFoundException $e) { - $locales = array(); + $qb = $this->db->createQueryBuilder() + ->addSelect('DISTINCT ' . $this->db->quoteIdentifier($this->config->getLocaleColumn()) . ' AS locale') + ->from($this->db->quoteIdentifier($this->config->getTableName())); + return Helpers::arrayColumn($qb->execute()->fetchAll(), 'locale', 'locale'); + + } catch (TableNotFoundException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); } - return $locales; } - protected function getResourceName() + + /** + * {@inheritdoc} + */ + public function setupDatabase($createSchema = FALSE) { - return DatabaseResource::DOCTRINE; + $schemaManager = $this->db->getSchemaManager(); + $platform = $this->db->getDatabasePlatform(); + + if (!$schemaManager->tablesExist($this->config->getTableName())) { + $table = $schemaManager->createSchema()->createTable($this->config->getTableName()); + $table->addColumn($this->config->getKeyColumn(), Type::STRING); + $table->addColumn($this->config->getLocaleColumn(), Type::STRING); + $table->addColumn($this->config->getMessageColumn(), Type::TEXT); + $table->addColumn($this->config->getUpdatedAtColumn(), Type::DATETIME); + $table->setPrimaryKey(array($this->config->getKeyColumn(), $this->config->getLocaleColumn())); + $table->addIndex(array($this->config->getUpdatedAtColumn())); + + } else { + $table = $schemaManager->createSchema()->getTable($this->config->getTableName()); + } + + if ($createSchema === TRUE) { + try { + $schemaManager->createTable($table); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } + } + + return $platform->getCreateTableSQL($table); } + + protected function getTranslations($locale) { - $qb = $this->conn->createQueryBuilder() - ->addSelect($this->conn->quoteIdentifier($this->key).' AS '.$this->conn->quoteIdentifier('key')) - ->addSelect($this->conn->quoteIdentifier($this->locale).' AS locale') - ->addSelect($this->conn->quoteIdentifier($this->message).' AS message') - ->from($this->conn->quoteIdentifier($this->table)) - ->where("locale = :locale") - ->setParameter('locale', $locale); - return $qb->execute()->fetchAll(); + try { + $qb = $this->db->createQueryBuilder() + ->addSelect($this->db->quoteIdentifier($this->config->getKeyColumn()) . ' AS ' . $this->db->quoteIdentifier('key')) + ->addSelect($this->db->quoteIdentifier($this->config->getLocaleColumn()) . ' AS locale') + ->addSelect($this->db->quoteIdentifier($this->config->getMessageColumn()) . ' AS message') + ->from($this->db->quoteIdentifier($this->config->getTableName())) + ->where($this->db->quoteIdentifier($this->config->getLocaleColumn()) . " = :locale") + ->setParameter('locale', $locale); + + return $qb->execute()->fetchAll(); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } } + + /** - * @param $locale + * @param string $locale * @return \DateTime */ protected function getLastUpdate($locale) { - $qb = $this->conn->createQueryBuilder() - ->addSelect($this->conn->quoteIdentifier($this->updatedAt).' AS '.$this->conn->quoteIdentifier('updated_at')) - ->from($this->conn->quoteIdentifier($this->table)) - ->where($this->conn->quoteIdentifier($this->locale).' = :locale') - ->orderBy('updated_at', Criteria::DESC) - ->setMaxResults(1) - ->setParameter('locale', $locale); - $updatedAt = $qb->execute()->fetchColumn(); - $dateTime = new \DateTime($updatedAt); - if ($updatedAt === NULL) { - $dateTime->setTimestamp(0); + try { + $updatedAt = $this->db->createQueryBuilder() + ->addSelect($this->db->quoteIdentifier($this->config->getUpdatedAtColumn()) . ' AS ' . $this->db->quoteIdentifier('updated_at')) + ->from($this->db->quoteIdentifier($this->config->getTableName())) + ->where($this->db->quoteIdentifier($this->config->getLocaleColumn()) . ' = :locale') + ->orderBy('updated_at', Criteria::DESC) + ->setMaxResults(1) + ->setParameter('locale', $locale) + ->execute()->fetchColumn(); + + $dateTime = new \DateTime($updatedAt); + if ($updatedAt === NULL) { + $dateTime->setTimestamp(0); + } + + return $dateTime; + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); } - return $dateTime; + } + + + + protected function getResourceName() + { + return DatabaseResource::DOCTRINE; } } diff --git a/src/Kdyby/Translation/Loader/IDatabaseLoader.php b/src/Kdyby/Translation/Loader/IDatabaseLoader.php index 0ac0176f..331fb7a1 100644 --- a/src/Kdyby/Translation/Loader/IDatabaseLoader.php +++ b/src/Kdyby/Translation/Loader/IDatabaseLoader.php @@ -1,14 +1,47 @@ + */ interface IDatabaseLoader extends LoaderInterface { + /** + * @return array + */ public function getLocales(); + + + /** + * @param Translator $translator + * @return void + */ public function addResources(Translator $translator); + + + + /** + * Creates the schema in database. + * + * @param bool $createSchema Should it also execute the queries? + * @return array The queries that were (or would have been) executed + */ + public function setupDatabase($createSchema = FALSE); + } diff --git a/src/Kdyby/Translation/Loader/NetteDbLoader.php b/src/Kdyby/Translation/Loader/NetteDbLoader.php index c76170ae..a9007335 100644 --- a/src/Kdyby/Translation/Loader/NetteDbLoader.php +++ b/src/Kdyby/Translation/Loader/NetteDbLoader.php @@ -1,73 +1,135 @@ + */ class NetteDbLoader extends DatabaseLoader { - /** @var Context */ - private $db; - /** - * @param Context $db + * @var Context */ - public function __construct(Context $db) + private $db; + + + + public function __construct(Context $db, Configuration $config) { + parent::__construct($config); $this->db = $db; } + + /** * @return array */ public function getLocales() { try { - $stmt = $this->db->query('SELECT DISTINCT '.$this->delimite($this->locale).' as locale FROM '.$this->delimite($this->table)); - $locales = $stmt->fetchPairs('locale', 'locale'); - } catch(DriverException $e) { - $locales = array(); + return $this->db + ->query('SELECT DISTINCT ' . $this->delimite($this->config->getLocaleColumn()) . ' as locale FROM ' . $this->delimite($this->config->getTableName())) + ->fetchPairs('locale', 'locale'); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); } - return $locales; } - protected function getResourceName() + + + /** + * {@inheritdoc} + */ + public function setupDatabase($createSchema = FALSE) { - return DatabaseResource::NETTE_DB; + throw new NotImplementedException; } + + + /** + * @param string $locale + * @return array|\Nette\Database\Table\IRow[] + */ protected function getTranslations($locale) { - $stmt = $this->db->table($this->table) - ->select($this->delimite($this->key).' AS '.$this->delimite('key').', '.$this->delimite($this->locale).' AS locale, '.$this->delimite($this->message).' AS message') - ->where("$this->locale = ?", $locale); - return $stmt->fetchAll(); + try { + return $this->db->table($this->config->getTableName()) + ->select($this->delimite($this->config->getKeyColumn()) . ' AS ' . $this->delimite('key') . ', ' . + $this->delimite($this->config->getLocaleColumn()) . ' AS locale, ' . + $this->delimite($this->config->getMessageColumn()) . ' AS message') + ->where($this->config->getLocaleColumn() . ' = ?', $locale) + ->fetchAll(); + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); + } } + + /** - * @param $locale + * @param string $locale * @return \DateTime */ protected function getLastUpdate($locale) { - $updatedAt = $this->db->table($this->table) - ->select($this->delimite($this->updatedAt).' AS '.$this->delimite('updated_at')) - ->where($this->delimite($this->locale).' = ?', $locale) - ->order('updated_at DESC') - ->limit(1) - ->fetchField('updated_at'); - if ($updatedAt === NULL) { - $updatedAt = new \DateTime(); - $updatedAt->setTimestamp(0); + try { + $row = $this->db->table($this->config->getTableName()) + ->select($this->delimite($this->config->getUpdatedAtColumn()) . ' AS ' . $this->delimite('updated_at')) + ->where($this->delimite($this->config->getLocaleColumn()) . ' = ?', $locale) + ->order('updated_at DESC') + ->limit(1) + ->fetch(); + + $updatedAt = $row['updated_at']; + if (empty($updatedAt)) { + $updatedAt = new \DateTime(); + $updatedAt->setTimestamp(0); + } + + return $updatedAt; + + } catch (DriverException $e) { + throw new DatabaseException($e->getMessage(), 0, $e); } - return $updatedAt; } + + + /** + * @return string + */ + protected function getResourceName() + { + return DatabaseResource::NETTE_DB; + } + + + private function delimite($name) { return $this->db->getConnection()->getSupplementalDriver()->delimite($name); } + } diff --git a/src/Kdyby/Translation/Resource/DatabaseResource.php b/src/Kdyby/Translation/Resource/DatabaseResource.php index 2d6c9586..c567d257 100644 --- a/src/Kdyby/Translation/Resource/DatabaseResource.php +++ b/src/Kdyby/Translation/Resource/DatabaseResource.php @@ -1,55 +1,78 @@ + */ class DatabaseResource implements ResourceInterface { - const DOCTRINE = 'doctrine'; - const NETTE_DB = 'nettedb'; - - /** - * @var string|false - */ - private $resource; - - private $lastUpdated; - - /** - * @param string $resource The file path to the resource - * @param int $lastUpdated timestamp - */ - public function __construct($resource, $lastUpdated) - { - $this->resource = $resource; - $this->lastUpdated = $lastUpdated; - } - - /** - * {@inheritdoc} - */ - public function __toString() - { - return (string) $this->resource; - } - - /** - * {@inheritdoc} - */ - public function getResource() - { - return $this->resource; - } - - /** - * {@inheritdoc} - */ - public function isFresh($timestamp) - { - return $this->lastUpdated <= $timestamp; - } + const DOCTRINE = 'doctrine'; + const NETTE_DB = 'nettedb'; + + /** + * @var string|boolean + */ + private $resource; + + /** + * @var int + */ + private $lastUpdated; + + + + /** + * @param string $resource The file path to the resource + * @param int $lastUpdated timestamp + */ + public function __construct($resource, $lastUpdated) + { + $this->resource = $resource; + $this->lastUpdated = $lastUpdated; + } + + + + /** + * {@inheritdoc} + */ + public function getResource() + { + return $this->resource; + } + + + + /** + * {@inheritdoc} + */ + public function isFresh($timestamp) + { + return $this->lastUpdated <= $timestamp; + } + + + + /** + * {@inheritdoc} + */ + public function __toString() + { + return (string) $this->resource; + } } diff --git a/src/Kdyby/Translation/Translator.php b/src/Kdyby/Translation/Translator.php index 8c71b3ec..2167d2e0 100644 --- a/src/Kdyby/Translation/Translator.php +++ b/src/Kdyby/Translation/Translator.php @@ -161,7 +161,7 @@ public function trans($message, array $parameters = array(), $domain = NULL, $lo } if ($domain === NULL) { - list($domain, $id) = $this->extractMessageDomain($message); + list($domain, $id) = Helpers::extractMessageDomain($message); } else { $id = $message; @@ -190,7 +190,7 @@ public function transChoice($message, $number, array $parameters = array(), $dom } if ($domain === NULL) { - list($domain, $id) = $this->extractMessageDomain($message); + list($domain, $id) = Helpers::extractMessageDomain($message); } else { $id = $message; @@ -400,24 +400,6 @@ protected function assertValidLocale($locale) - /** - * @param $message - * @return array - */ - private function extractMessageDomain($message) - { - if (strpos($message, '.') !== FALSE && strpos($message, ' ') === FALSE) { - list($domain, $message) = explode('.', $message, 2); - - } else { - $domain = 'messages'; - } - - return array($domain, $message); - } - - - /** * @param null|string $whitelist * @return null|string diff --git a/src/Kdyby/Translation/exceptions.php b/src/Kdyby/Translation/exceptions.php index 7a242c4d..b8273167 100644 --- a/src/Kdyby/Translation/exceptions.php +++ b/src/Kdyby/Translation/exceptions.php @@ -10,8 +10,6 @@ namespace Kdyby\Translation; - - /** * @author Filip Procházka */ @@ -32,6 +30,9 @@ class InvalidArgumentException extends \InvalidArgumentException implements Exce +/** + * @author Filip Procházka + */ class InvalidStateException extends \RuntimeException implements Exception { @@ -56,3 +57,23 @@ class LoaderNotFoundException extends \RuntimeException implements Exception { } + + + +/** + * The exception that is thrown when a requested method or operation is not implemented. + */ +class NotImplementedException extends \LogicException implements Exception +{ + +} + + + +/** + * @author Filip Procházka + */ +class DatabaseException extends \RuntimeException implements Exception +{ + +} diff --git a/tests/KdybyTests/Translation/TranslateMacros.phpt b/tests/KdybyTests/Translation/TranslateMacros.phpt index 38eb0354..7d12539f 100644 --- a/tests/KdybyTests/Translation/TranslateMacros.phpt +++ b/tests/KdybyTests/Translation/TranslateMacros.phpt @@ -19,11 +19,14 @@ use Tester\Assert; require_once __DIR__ . '/../bootstrap.php'; + class ControlMock extends Nette\Application\UI\Control { } + + /** * @author Filip Procházka */ @@ -157,4 +160,6 @@ front.missingKey.namedHelloCounting' . "\n", (string) $template->setFile(__DIR__ } + + \run(new TranslateMacrosTest()); diff --git a/tests/KdybyTests/Translation/TranslationDumper.phpt b/tests/KdybyTests/Translation/TranslationDumper.doctrine.phpt similarity index 79% rename from tests/KdybyTests/Translation/TranslationDumper.phpt rename to tests/KdybyTests/Translation/TranslationDumper.doctrine.phpt index 4a9b0be4..8c28853c 100644 --- a/tests/KdybyTests/Translation/TranslationDumper.phpt +++ b/tests/KdybyTests/Translation/TranslationDumper.doctrine.phpt @@ -11,6 +11,7 @@ namespace KdybyTests\Translation; use Kdyby; +use Kdyby\Translation\DI\Configuration; use Kdyby\Translation\TranslationLoader; use Nette; use Symfony; @@ -25,32 +26,44 @@ require_once __DIR__ . '/../bootstrap.php'; /** * @author Filip Procházka */ -class TranslationDumperTest extends TestCase +class TranslationDumperDoctrineTest extends TestCase { - /** @var Doctrine\DBAL\Connection $connection */ - private $connection; - /** @var \Nette\DI\Container */ + /** + * @var Doctrine\DBAL\Connection + */ + private $db; + + /** + * @var \Nette\DI\Container + */ private $container; - public function __construct() + + + protected function setUp() { + parent::setUp(); Tester\Environment::lock('db', dirname(TEMP_DIR)); - $this->container = $this->createContainer(); - $this->connection = $this->container->getByType('Doctrine\DBAL\Connection'); + $this->container = $this->createContainer('doctrine'); + $this->db = $this->container->getByType('Doctrine\DBAL\Connection'); + $this->db->executeUpdate(file_get_contents(__DIR__ . '/../init.sql')); } - protected function setUp() + + + public function tearDown() { - parent::setUp(); - $this->connection->executeUpdate(file_get_contents(__DIR__ . '/../init.sql')); + parent::tearDown(); + $this->db->executeUpdate(file_get_contents(__DIR__ . '/../clear.sql')); } + public function testChangeTranslations() { $loader = new TranslationLoader(); - $loader->addLoader('database', $dbLoader = new Kdyby\Translation\Loader\DoctrineLoader($this->connection)); + $loader->addLoader('database', $dbLoader = new Kdyby\Translation\Loader\DoctrineLoader($this->db, new Configuration())); $catalogue = new Kdyby\Translation\MessageCatalogue('cs_CZ'); $loader->loadResource('database', Kdyby\Translation\Resource\DatabaseResource::DOCTRINE, NULL, $catalogue); @@ -74,7 +87,7 @@ class TranslationDumperTest extends TestCase public function testAddTranslations() { $loader = new TranslationLoader(); - $loader->addLoader('database', $dbLoader = new Kdyby\Translation\Loader\DoctrineLoader($this->connection)); + $loader->addLoader('database', $dbLoader = new Kdyby\Translation\Loader\DoctrineLoader($this->db, new Configuration())); $catalogue = new Kdyby\Translation\MessageCatalogue('cs_CZ'); $loader->loadResource('database', Kdyby\Translation\Resource\DatabaseResource::DOCTRINE, NULL, $catalogue); @@ -82,7 +95,6 @@ class TranslationDumperTest extends TestCase Assert::false($catalogue->defines('footer', 'messages')); Assert::false($catalogue->defines('farewell', 'front')); - $writer = $this->container->getByType('Symfony\Component\Translation\Writer\TranslationWriter'); $catalogue->add(array('farewell' => 'Sbohem'), 'front'); $catalogue->add(array('footer' => 'Zápatí'), 'messages'); @@ -92,13 +104,8 @@ class TranslationDumperTest extends TestCase Assert::true($catalogue->defines('farewell', 'front')); } - public function tearDown() - { - parent::tearDown(); +} - $this->connection->executeUpdate(file_get_contents(__DIR__ . '/../clear.sql')); - } -} -\run(new TranslationDumperTest()); +\run(new TranslationDumperDoctrineTest()); diff --git a/tests/KdybyTests/Translation/TranslationLoader.doctrine.phpt b/tests/KdybyTests/Translation/TranslationLoader.doctrine.phpt new file mode 100644 index 00000000..ac2ed5f2 --- /dev/null +++ b/tests/KdybyTests/Translation/TranslationLoader.doctrine.phpt @@ -0,0 +1,107 @@ + + * @package Kdyby\Translation + */ + +namespace KdybyTests\Translation; + +use Kdyby; +use Kdyby\Translation\DI\Configuration; +use Kdyby\Translation\Loader\DoctrineLoader; +use Kdyby\Translation\MessageCatalogue; +use Kdyby\Translation\Resource\DatabaseResource; +use Kdyby\Translation\TranslationLoader; +use Nette; +use Symfony; +use Tester; +use Tester\Assert; +use Doctrine; + +require_once __DIR__ . '/../bootstrap.php'; + + + +/** + * @author Filip Procházka + */ +class TranslationLoaderDoctrineTest extends TestCase +{ + + /** + * @var Doctrine\DBAL\Connection + */ + private $db; + + /** + * @var \Nette\DI\Container + */ + private $container; + + + + protected function setUp() + { + parent::setUp(); + Tester\Environment::lock('db', dirname(TEMP_DIR)); + $this->container = $this->createContainer('doctrine'); + $this->db = $this->container->getByType('Doctrine\DBAL\Connection'); + $this->db->executeUpdate(file_get_contents(__DIR__ . '/../init.sql')); + } + + + + public function tearDown() + { + parent::tearDown(); + $this->db->executeUpdate(file_get_contents(__DIR__ . '/../clear.sql')); + } + + + + public function testAddLoaders() + { + $loader = new TranslationLoader(); + Assert::same(array(), $loader->getLoaders()); + + $loader->addLoader('database', $dbLoader = new DoctrineLoader($this->db, new Configuration())); + Assert::same(array('database' => $dbLoader), $loader->getLoaders()); + } + + + + public function testLoadResources() + { + $loader = new TranslationLoader(); + $loader->addLoader('database', $dbLoader = new DoctrineLoader($this->db, new Configuration())); + + $catalogue = new MessageCatalogue('cs_CZ'); + $loader->loadResource('database', DatabaseResource::DOCTRINE, NULL, $catalogue); + + Assert::true($catalogue->defines('header', 'front')); + Assert::true($catalogue->defines('hello', 'messages')); + + $catalogue = new MessageCatalogue('en'); + $loader->loadResource('database', DatabaseResource::DOCTRINE, NULL, $catalogue); + + Assert::true($catalogue->defines('header', 'front')); + Assert::true($catalogue->defines('hello', 'messages')); + } + + + + public function testLoadLocales() + { + $dbLoader = new DoctrineLoader($this->db, new Configuration()); + Assert::same(array('cs_CZ' => 'cs_CZ', 'en' => 'en'), $dbLoader->getLocales()); + } + +} + + + +\run(new TranslationLoaderDoctrineTest()); diff --git a/tests/KdybyTests/Translation/TranslationLoader.neon.phpt b/tests/KdybyTests/Translation/TranslationLoader.neon.phpt new file mode 100644 index 00000000..e0b75891 --- /dev/null +++ b/tests/KdybyTests/Translation/TranslationLoader.neon.phpt @@ -0,0 +1,57 @@ + + * @package Kdyby\Translation + */ + +namespace KdybyTests\Translation; + +use Kdyby; +use Kdyby\Translation\TranslationLoader; +use Nette; +use Symfony; +use Tester; +use Tester\Assert; +use Doctrine; + +require_once __DIR__ . '/../bootstrap.php'; + + + +/** + * @author Filip Procházka + */ +class TranslationLoaderNeonTest extends TestCase +{ + + public function testAddLoaders() + { + $loader = new TranslationLoader(); + Assert::same(array(), $loader->getLoaders()); + + $loader->addLoader('neon', $neonLoader = new Kdyby\Translation\Loader\NeonFileLoader()); + Assert::same(array('neon' => $neonLoader), $loader->getLoaders()); + } + + + + public function loadResource() + { + $loader = new TranslationLoader(); + $loader->addLoader('neon', new Kdyby\Translation\Loader\NeonFileLoader()); + + $catalogue = new Kdyby\Translation\MessageCatalogue('cs_CZ'); + $loader->loadResource('neon', __DIR__ . '/lang/front.cs_CZ.neon', 'front', $catalogue); + + Assert::true($catalogue->defines('front.homepage.hello')); + } + +} + + + +\run(new TranslationLoaderNeonTest()); diff --git a/tests/KdybyTests/Translation/TranslationLoader.netteDb.phpt b/tests/KdybyTests/Translation/TranslationLoader.netteDb.phpt new file mode 100644 index 00000000..7e39f88c --- /dev/null +++ b/tests/KdybyTests/Translation/TranslationLoader.netteDb.phpt @@ -0,0 +1,107 @@ + + * @package Kdyby\Translation + */ + +namespace KdybyTests\Translation; + +use Kdyby; +use Kdyby\Translation\DI\Configuration; +use Kdyby\Translation\Loader\NetteDbLoader; +use Kdyby\Translation\MessageCatalogue; +use Kdyby\Translation\Resource\DatabaseResource; +use Kdyby\Translation\TranslationLoader; +use Nette; +use Symfony; +use Tester; +use Tester\Assert; +use Doctrine; + +require_once __DIR__ . '/../bootstrap.php'; + + + +/** + * @author Filip Procházka + */ +class TranslationLoaderNetteDbTest extends TestCase +{ + + /** + * @var \Nette\Database\Context + */ + private $db; + + /** + * @var \Nette\DI\Container + */ + private $container; + + + + protected function setUp() + { + parent::setUp(); + Tester\Environment::lock('db', dirname(TEMP_DIR)); + $this->container = $this->createContainer('netteDb'); + $this->db = $this->container->getByType('Nette\Database\Context'); + Nette\Database\Helpers::loadFromFile($this->db->getConnection(), __DIR__ . '/../init.sql'); + } + + + + public function tearDown() + { + parent::tearDown(); + Nette\Database\Helpers::loadFromFile($this->db->getConnection(), __DIR__ . '/../clear.sql'); + } + + + + public function testAddLoaders() + { + $loader = new TranslationLoader(); + Assert::same(array(), $loader->getLoaders()); + + $loader->addLoader('database', $dbLoader = new NetteDbLoader($this->db, new Configuration())); + Assert::same(array('database' => $dbLoader), $loader->getLoaders()); + } + + + + public function testLoadResources() + { + $loader = new TranslationLoader(); + $loader->addLoader('database', $dbLoader = new NetteDbLoader($this->db, new Configuration())); + + $catalogue = new MessageCatalogue('cs_CZ'); + $loader->loadResource('database', DatabaseResource::NETTE_DB, NULL, $catalogue); + + Assert::true($catalogue->defines('header', 'front')); + Assert::true($catalogue->defines('hello', 'messages')); + + $catalogue = new MessageCatalogue('en'); + $loader->loadResource('database', DatabaseResource::NETTE_DB, NULL, $catalogue); + + Assert::true($catalogue->defines('header', 'front')); + Assert::true($catalogue->defines('hello', 'messages')); + } + + + + public function testLoadLocales() + { + $dbLoader = new NetteDbLoader($this->db, new Configuration()); + Assert::same(array('cs_CZ' => 'cs_CZ', 'en' => 'en'), $dbLoader->getLocales()); + } + +} + + + +\run(new TranslationLoaderNetteDbTest()); diff --git a/tests/KdybyTests/Translation/TranslationLoader.phpt b/tests/KdybyTests/Translation/TranslationLoader.phpt deleted file mode 100644 index 7d64be12..00000000 --- a/tests/KdybyTests/Translation/TranslationLoader.phpt +++ /dev/null @@ -1,100 +0,0 @@ - - * @package Kdyby\Translation - */ - -namespace KdybyTests\Translation; - -use Kdyby; -use Kdyby\Translation\TranslationLoader; -use Nette; -use Symfony; -use Tester; -use Tester\Assert; -use Doctrine; -use Tracy\Debugger; - -require_once __DIR__ . '/../bootstrap.php'; - - - -/** - * @author Filip Procházka - */ -class TranslationLoaderTest extends TestCase -{ - /** @var Doctrine\DBAL\Connection $connection */ - private $connection; - - /** @var \Nette\DI\Container */ - private $container; - - public function __construct() - { - Tester\Environment::lock('db', dirname(TEMP_DIR)); - $this->container = $this->createContainer(); - $this->connection = $this->container->getByType('Doctrine\DBAL\Connection'); - } - - protected function setUp() - { - parent::setUp(); - $this->connection->executeUpdate(file_get_contents(__DIR__ . '/../init.sql')); - } - - - public function testAddLoaders() - { - - $loader = new TranslationLoader(); - Assert::same(array(), $loader->getLoaders()); - - $loader->addLoader('neon', $neonLoader = new Kdyby\Translation\Loader\NeonFileLoader()); - $loader->addLoader('database', $dbLoader = new Kdyby\Translation\Loader\DoctrineLoader($this->connection)); - Assert::same(array('neon' => $neonLoader, 'database' => $dbLoader), $loader->getLoaders()); - } - - - - public function testLoadResources() - { - $loader = new TranslationLoader(); - $loader->addLoader('neon', new Kdyby\Translation\Loader\NeonFileLoader()); - $loader->addLoader('database', $dbLoader = new Kdyby\Translation\Loader\DoctrineLoader($this->connection)); - - $catalogue = new Kdyby\Translation\MessageCatalogue('cs_CZ'); - $loader->loadResource('neon', __DIR__ . '/lang/front.cs_CZ.neon', 'front', $catalogue); - $loader->loadResource('database', Kdyby\Translation\Resource\DatabaseResource::DOCTRINE, NULL, $catalogue); - - Assert::true($catalogue->defines('homepage.hello', 'front')); - Assert::true($catalogue->defines('header', 'front')); - Assert::true($catalogue->defines('hello', 'messages')); - - $catalogue = new Kdyby\Translation\MessageCatalogue('en'); - $loader->loadResource('database', Kdyby\Translation\Resource\DatabaseResource::DOCTRINE, NULL, $catalogue); -// - Assert::true($catalogue->defines('header', 'front')); - Assert::true($catalogue->defines('hello', 'messages')); - - } - - public function testLoadLocales() - { - $dbLoader = new Kdyby\Translation\Loader\DoctrineLoader($this->connection); - Assert::same(array('cs_CZ', 'en'), $dbLoader->getLocales()); - } - - public function tearDown() - { - parent::tearDown(); - $this->connection->executeUpdate(file_get_contents(__DIR__ . '/../clear.sql')); - } - -} - -\run(new TranslationLoaderTest()); diff --git a/tests/KdybyTests/Translation/config/doctrine.neon b/tests/KdybyTests/Translation/config/doctrine.neon new file mode 100644 index 00000000..46257618 --- /dev/null +++ b/tests/KdybyTests/Translation/config/doctrine.neon @@ -0,0 +1,14 @@ +extensions: + events: Kdyby\Events\DI\EventsExtension + annotations: Kdyby\Annotations\DI\AnnotationsExtension + doctrine: Kdyby\Doctrine\DI\OrmExtension + + +translation: + database: + loader: doctrine + + +doctrine: + driver: pdo_sqlite + memory: true diff --git a/tests/KdybyTests/Translation/config/netteDb.neon b/tests/KdybyTests/Translation/config/netteDb.neon new file mode 100644 index 00000000..e84e185b --- /dev/null +++ b/tests/KdybyTests/Translation/config/netteDb.neon @@ -0,0 +1,7 @@ +translation: + database: + loader: nettedb + + +database: + dsn: "sqlite::memory:" diff --git a/tests/KdybyTests/nette-reset.neon b/tests/KdybyTests/nette-reset.neon index 8ed66d82..d134e92f 100644 --- a/tests/KdybyTests/nette-reset.neon +++ b/tests/KdybyTests/nette-reset.neon @@ -7,25 +7,16 @@ common: cacheStorage: class: Nette\Caching\Storages\MemoryStorage + extensions: console: Kdyby\Console\DI\ConsoleExtension - events: Kdyby\Events\DI\EventsExtension - annotations: Kdyby\Annotations\DI\AnnotationsExtension - doctrine: Kdyby\Doctrine\DI\OrmExtension + translation: whitelist: [cs, sk, en] resolvers: session: on - database: - loader: doctrine - - doctrine: - driver: pdo_sqlite - memory: true - database: - dsn: "sqlite::memory:" v22 < common: nette: