Skip to content

Commit

Permalink
Added loaders and dumpers for nette database and Doctrine DBAL.
Browse files Browse the repository at this point in the history
Fixed BC break in php 5.4.

Fixed BC break in php 5.4.

Line endings are only LF instead of CRLF.

Removed bardumps.

Added whitespaces to end of files.

Removed all barDumps.

Added console as extension to tests because of doctrine dev dependency.

Fixed bug in nette database dumper.
Added compatibility to nette 2.3.

Refactoring. Better abstract classes and deleted unused interface.

Refactoring. You can only use one database driver at time. You can use your own loader and dumper.
Added updated_at column for invalidating translations.

Fixed missing whitespace.

Fixed whitespace.

Fixed header.

Uncommented commit in dumper.

Added listener for future use and added mysql queries for creating translation table to dumpers.

Fixed whitespace bug in codechecker.

cs

Added command for creating table.
Refactored.

Added documentation.

Removed commented part of code.

Updated documentation.

Refactoring.

Updated documentation.

Small refactoring.

Refactoring.

Added dependencies to tests.

Fixed tabs.

Fixed configuration.

Fixed configuration.

Refactoring. Added test.
Hopefully fixed compatibility.

bugfix

fixed dependency

Added table creation.

fixed sql data inicialization.

Added loader tests.

Added another tests.
ws fix

ws

ws

fix

Added tests.

Fixed BC break.

fix

drobná úprava markdownu v dokumentaci pro lepší čitelnost

Fixed column names.

opraven composer.json

přidána classmap

nette db bugfix

odebrán Debugger log

ugfix for dumping empty domain

nette db bugfix

fixed invalid insert when message column is not null

When no datetime is found in updatedAt column, updated at is datetime with timestamp 0.

correct usage of delimiter for databases

correct usage of delimiter for databases also in loaders

correct usage of delimiter for databases everywhere

bugfixes

cs

added lock

typo

checking of testing table creation

typo

typo

fixed sqlite compatibility and connection instances in tests

removed some debug commands

usedParseService instead of self::filterArgs

fixed mixed indenting

bugfix

bugfix for keys where some keys have domain and some do not have domain
  • Loading branch information
racinmat authored and fprochazka committed Oct 17, 2015
1 parent 3e13f38 commit 8094b40
Show file tree
Hide file tree
Showing 22 changed files with 1,153 additions and 28 deletions.
10 changes: 7 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
"tracy/tracy": "Diagnostics tool from Nette",
"symfony/locale": "Locale component provides fallback code to handle cases when the intl extension is missing.",
"kdyby/console": "If you wanna use extract command and much others, install also console.",
"symfony/yaml": "If you wanna store translations in YAML format - supports multiline strings."
"symfony/yaml": "If you wanna store translations in YAML format - supports multiline strings.",
"kdyby/doctrine": "If you wanna store translations in database and use Doctrine.",
"nette/database": "If you wanna store translations in database and use Nette Database.",
"doctrine/dbal": "If you wanna create database table by Symfony command from your config."
},
"require-dev": {
"nette/application": "~2.3@dev",
Expand All @@ -58,10 +61,11 @@
"nette/utils": "~2.3@dev",
"latte/latte": "~2.3@dev",
"tracy/tracy": "~2.3@dev",

"symfony/console": "~2.3",
"nette/tester": "~1.4",
"mockery/mockery": "~0.9"
"mockery/mockery": "~0.9",
"kdyby/doctrine": "~2.3",
"kdyby/events": "~2.3.1"
},
"autoload": {
"psr-0": {
Expand Down
108 changes: 108 additions & 0 deletions docs/en/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,111 @@ translation:
resolvers:
header: off
```


## Database integration

### Loaders

Kdyby\Translation can use two database libraries for handling database translations: [Nette Database](https://github.com/nette/database) and [Doctrine 2 DBAL](https://github.com/doctrine/dbal)

There is minimal configuration which needs to be added to your config.neon:

```yml
translation:
database:
loader: doctrine
```

Loader can have values: `doctrine` or `nettedb`, it depends, which database library you use.
You can also use your own Loader, then you put to your config.neon full name with namespace:

```yml
translation:
database:
loader: \Namespace\CustomLoader
```

The loader needs to implement the [Symfony\Component\Translation\Loader\LoaderInterface](https://github.com/symfony/Translation/blob/3ba54181c8386b180999d942bf33681a726bb70f/Loader/LoaderInterface.php)
but it will be much more comfortable, when you extend abstract class Kdyby\Translation\Loader\DatabaseLoader, which handles all logic and all you have to do is to implement queries for retrieving translations.

### Table structure and configuration

The table in database has 4 columns:
- `key` (like key in your .neon translations, and key, which you write to translate method)
- `locale`: language of message
- `message`: actual text of message
- `updatedAt`: column with datetime of last update. This one is used for cache invalidation because of Kdyby\Translation's sophisticated caching.

You can configure names of columns and name of translation table in your database like this

```yml
translation:
database:
table: translationTableName
columns:
key: keyColumnName
locale: localeColumnName
message: messageColumnName
updatedAt: lastUpdateColumnName
```

Default values are

```yml
translation:
database:
table: translations
columns:
key: key
locale: locale
message: message
updatedAt: updated_at
```

### Generating table via Symfony Commands

If you want to have your translation table generated, you need to download the [Doctrine 2 DBAL](https://github.com/doctrine/dbal) library
and [Kdyby\Console](https://github.com/Kdyby/Console) library over Composer and then you can use kdyby:translation-create-table command to generate table

```sh
$ kdyby:translation-create-table --dump-sql dumps SQL query, but does not execute it.
$ kdyby:translation-create-table --force executes SQL query.
```


### Modifying translations

You can modify your translations in database in any way you are used to, but you must update the value in updatedAt column.
Or you can let Kdyby\Translation do that for you.

Following snippet of code will show you how you can modify translations in Presenter and save them using Kdyby\Translation (only for illustration, please, keep this in your Model layer)

```php
<?php

namespace App\Presenters;

use Kdyby\Translation\Translator;
use Symfony\Component\Translation\Writer\TranslationWriter;
use Nette;

class TranslationPresenter extends BasePresenter
{
/** @var Translator @inject */
public $translator;

/** @var TranslationWriter @inject */
public $writer;

public function renderDefault()
{
$catalogue = $this->translator->getCatalogue('en'); //catalogue is object with all translations for given language

$catalogue->set('messages.homepage.hello', 'Hi'); //using this method, you can change translations. Or add tran
$catalogue->add(['messages.homepage.farewell' => 'Farewell']); //using this method, you can add new translations. You have to save them in associative array: key => message

$this->writer->writeTranslations($catalogue, 'database'); //with this, you save translations. If you use 'neon' or any other format instead of 'database', you can save all translation to neon files (or another supported format).

}
```
113 changes: 113 additions & 0 deletions src/Kdyby/Translation/Console/CreateTableCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

/**
* This file is part of the Kdyby (http://www.kdyby.org)
*
* Copyright (c) 2008 Filip Procházka ([email protected])
*
* For the full copyright and license information, please view the file license.txt that was distributed with this source code.
*/

namespace Kdyby\Translation\Console;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\AbstractSchemaManager;
use Doctrine\DBAL\Types\Type;
use Kdyby;
use Nette;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;



/**
* @author Filip Procházka <[email protected]>
*/
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 string */
public $message;

/** @var string */
public $updatedAt;

protected function configure()
{
$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.'
)
));
}


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');
}


protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$input->getOption('dump-sql') && !$input->getOption('force')) {
$output->writeln('<error>You must run the command either with --dump-sql or --force.</error>');
return;
}

if ($this->schemaManager->tablesExist($this->table)) {
$output->writeln('Table already exists.');
return;
}

$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')) {
$this->schemaManager->createTable($table);
$output->writeln(sprintf('Database schema updated successfully! Translation table created.'));
}
}

}
Loading

0 comments on commit 8094b40

Please sign in to comment.