Skip to content
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

Db drivers #89

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
8 changes: 7 additions & 1 deletion 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 @@ -59,7 +62,10 @@
"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"
},
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).

}
```
84 changes: 84 additions & 0 deletions src/Kdyby/Translation/Console/CreateTableCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?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\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;



/**
* @author Azathoth <[email protected]>
*
* @method ContainerHelper|Helper getHelper(string $name)
*/
class CreateTableCommand extends Command
{

/**
* @var Kdyby\Translation\Loader\IDatabaseLoader
*/
private $databaseLoader;



protected function configure()
{
$this->setName('kdyby:translation:create-table')
->setDescription('Builds query for creating of database table.')
->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)
{
$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('<error>You must run the command either with --dump-sql or --force.</error>');
return 1;
}

try {
$queries = $this->databaseLoader->setupDatabase($input->getOption('force'));

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;

} catch (Kdyby\Translation\DatabaseException $e) {
$this->getApplication()->renderException($e, $output);
return 1;
}
}

}
12 changes: 8 additions & 4 deletions src/Kdyby/Translation/Console/ExtractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
namespace Kdyby\Translation\Console;

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;
Expand All @@ -22,6 +24,7 @@

/**
* @author Filip Procházka <[email protected]>
* @method ContainerHelper|Helper getHelper(string $name)
*/
class ExtractCommand extends Command
{
Expand Down Expand Up @@ -70,7 +73,8 @@ class ExtractCommand extends Command

protected function configure()
{
$this->setName('kdyby:translation-extract')
$this->setName('kdyby:translation:extract')
->setAliases(['kdyby:translation-extract'])
->setDescription('Extracts strings from application to translation files')
->addOption('scan-dir', 'd', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, "The directory to parse the translations. Can contain %placeholders%.", array('%appDir%'))
->addOption('output-format', 'f', InputOption::VALUE_REQUIRED, "Format name of the messages.")
Expand All @@ -83,10 +87,10 @@ protected function configure()

protected function initialize(InputInterface $input, OutputInterface $output)
{
$this->translator = $this->getHelper('container')->getByType('Kdyby\Translation\Translator');
$this->writer = $this->getHelper('container')->getByType('Symfony\Component\Translation\Writer\TranslationWriter');
$this->extractor = $this->getHelper('container')->getByType('Symfony\Component\Translation\Extractor\ChainExtractor');
$this->serviceLocator = $this->getHelper('container')->getContainer();
$this->translator = $this->serviceLocator->getByType('Kdyby\Translation\Translator');
$this->writer = $this->serviceLocator->getByType('Symfony\Component\Translation\Writer\TranslationWriter');
$this->extractor = $this->serviceLocator->getByType('Symfony\Component\Translation\Extractor\ChainExtractor');
}


Expand Down
125 changes: 125 additions & 0 deletions src/Kdyby/Translation/DI/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?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\DI;

use Kdyby;
use Nette;



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

}
Loading