Skip to content

Synchronization #139

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

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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ A more complex example including database table with multilingual support is bel
'connection' => 'db', // connection identifier
'table' => '{{%language}}', // table name
'columns' => ['name', 'name_ascii'],// names of multilingual fields
'synchronize' => true, // save translates on changing source value. Translates will have 'pending' status till update.
'category' => 'database-table-name',// the category is the database table name
]
],
Expand Down Expand Up @@ -582,4 +583,4 @@ The MIT License (MIT). Please see [License File](LICENSE.md) for more informatio
[ico-downloads]: https://img.shields.io/packagist/dt/lajax/yii2-translate-manager.svg?style=flat

[link-packagist]: https://packagist.org/packages/lajax/yii2-translate-manager
[link-downloads]: https://packagist.org/packages/lajax/yii2-translate-manager
[link-downloads]: https://packagist.org/packages/lajax/yii2-translate-manager
2 changes: 1 addition & 1 deletion assets/javascripts/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var translate = (function () {
*/
function _translateLanguage($this) {
var $translation = $this.closest('tr').find('.translation');

$this.closest('tr').find('.pending-label').remove();
var data = {
id: $translation.data('id'),
language_id: $('#language_id').val(),
Expand Down
12 changes: 10 additions & 2 deletions assets/stylesheets/language.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ span.statistic {
position:relative;
cursor:help;
}
span.statistic span {
span.statistic span.done {
height:18px;
background:#5CB85C;
display:block;
float: left;
}

span.statistic span.pending {
height:18px;
background:#F0D91B;
display:block;
float: left;
}

span.statistic i {
Expand All @@ -22,4 +30,4 @@ span.statistic i {
top:0;
right:5px;
font-weight:bold;
}
}
28 changes: 23 additions & 5 deletions controllers/actions/SaveAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,30 @@ public function run()

$id = Yii::$app->request->post('id', 0);
$languageId = Yii::$app->request->post('language_id', Yii::$app->language);
$translation = Yii::$app->request->post('translation', '');

$languageTranslate = LanguageTranslate::findOne(['id' => $id, 'language' => $languageId]);

$regenerate = false;

if (trim($translation) == '') {
if ($languageTranslate && $languageTranslate->delete()) {
$regenerate = true;
} else {
return [];
}
} else {
$languageTranslate = $languageTranslate ?:
new LanguageTranslate(['id' => $id, 'language' => $languageId]);
$languageTranslate->translation = $translation;
$languageTranslate->status = 'done';

if ($languageTranslate->validate() && $languageTranslate->save()) {
$regenerate = true;
}
}

$languageTranslate = LanguageTranslate::findOne(['id' => $id, 'language' => $languageId]) ?:
new LanguageTranslate(['id' => $id, 'language' => $languageId]);

$languageTranslate->translation = Yii::$app->request->post('translation', '');
if ($languageTranslate->validate() && $languageTranslate->save()) {
if ($regenerate) {
$generator = new Generator($this->controller->module, $languageId);

$generator->run();
Expand Down
2 changes: 2 additions & 0 deletions controllers/actions/ScanAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ public function run()
$scanner->run();

$newDataProvider = $this->controller->createLanguageSourceDataProvider($scanner->getNewLanguageElements());
$updatedDataProvider = $this->_createLanguageSourceDataProvider($scanner->getUpdatedLanguageSourceIds());
$oldDataProvider = $this->_createLanguageSourceDataProvider($scanner->getRemovableLanguageSourceIds());

return $this->controller->render('scan', [
'newDataProvider' => $newDataProvider,
'updatedDataProvider' => $updatedDataProvider,
'oldDataProvider' => $oldDataProvider,
]);
}
Expand Down
22 changes: 22 additions & 0 deletions migrations/m200811_080242_synchronization.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
use yii\db\Migration;

/**
* @author Pavel Filippov <[email protected]>
*
* @since 1.0
*/
class m200811_080242_synchronization extends Migration
{
public function up()
{
$this->addColumn('language_source', 'sync_id', $this->string(256)->defaultValue('')->after('id'));
$this->addColumn('language_translate', 'status', $this->string(15)->defaultValue('done')->after('id'));
}

public function down()
{
$this->dropColumn('language_source', 'sync_id');
$this->dropColumn('language_translate', 'status');
}
}
9 changes: 4 additions & 5 deletions models/Language.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,16 @@ public function getGridStatistic()
}

$languageTranslates = LanguageTranslate::find()
->select(['language', 'COUNT(*) AS cnt'])
->select(['language', 'status', 'COUNT(*) AS cnt'])
->andWhere('translation IS NOT NULL')
->groupBy(['language'])
->groupBy(['language', 'status'])
->all();

foreach ($languageTranslates as $languageTranslate) {
$statistics[$languageTranslate->language] = floor(($languageTranslate->cnt / $count) * 100);
$statistics[$languageTranslate->language][$languageTranslate->status] = floor(($languageTranslate->cnt / $count) * 100);
}
}

return isset($statistics[$this->language_id]) ? $statistics[$this->language_id] : 0;
return isset($statistics[$this->language_id]) ? array_merge(['done' => 0, 'pending' => 0], $statistics[$this->language_id]) : ['done' => 0, 'pending' => 0];
}

/**
Expand Down
10 changes: 7 additions & 3 deletions models/LanguageSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* This is the model class for table "language_source".
*
* @property string $id
* @property string $sync_id
* @property string $category
* @property string $message
* @property string $source
Expand Down Expand Up @@ -54,6 +55,7 @@ public function rules()
return [
[['message'], 'string'],
[['category'], 'string', 'max' => 32],
[['sync_id'], 'string', 'max' => 256],
];
}

Expand All @@ -64,6 +66,7 @@ public function attributeLabels()
{
return [
'id' => Yii::t('model', 'ID'),
'sync_id' => Yii::t('model', 'Sync ID'),
'category' => Yii::t('model', 'Category'),
'message' => Yii::t('model', 'Message'),
];
Expand All @@ -80,10 +83,11 @@ public function insertLanguageItems($languageItems)
{
$data = [];
foreach ($languageItems as $category => $messages) {
foreach (array_keys($messages) as $message) {
foreach ($messages as $message => $sync_id) {
$data[] = [
$sync_id === true ? '' : $sync_id,
$category,
$message,
$message
];
}
}
Expand All @@ -92,7 +96,7 @@ public function insertLanguageItems($languageItems)
for ($i = 0; $i < $count; $i += self::INSERT_LANGUAGE_ITEMS_LIMIT) {
static::getDb()
->createCommand()
->batchInsert(static::tableName(), ['category', 'message'], array_slice($data, $i, self::INSERT_LANGUAGE_ITEMS_LIMIT))
->batchInsert(static::tableName(), ['sync_id', 'category', 'message'], array_slice($data, $i, self::INSERT_LANGUAGE_ITEMS_LIMIT))
->execute();
}

Expand Down
3 changes: 3 additions & 0 deletions models/LanguageTranslate.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* This is the model class for table "language_translate".
*
* @property string $id
* @property string $status
* @property string $language
* @property string $translation
* @property LanguageSource $LanguageSource
Expand Down Expand Up @@ -58,6 +59,7 @@ public function rules()
[['language'], 'exist', 'targetClass' => '\lajax\translatemanager\models\Language', 'targetAttribute' => 'language_id'],
[['translation'], 'string'],
[['language'], 'string', 'max' => 5],
[['status'], 'string', 'max' => 15],
];
}

Expand All @@ -68,6 +70,7 @@ public function attributeLabels()
{
return [
'id' => Yii::t('model', 'ID'),
'status' => Yii::t('model', 'Status'),
'language' => Yii::t('model', 'Language'),
'translation' => Yii::t('model', 'Translation'),
];
Expand Down
4 changes: 4 additions & 0 deletions services/Optimizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use yii\helpers\Console;
use lajax\translatemanager\models\LanguageSource;
use lajax\translatemanager\models\LanguageTranslate;

/**
* Optimizer class for optimizing database tables
Expand Down Expand Up @@ -53,6 +54,9 @@ public function run()

LanguageSource::deleteAll(['id' => $languageSourceIds]);

$numberOfDeletetRows = LanguageTranslate::deleteAll(['translation' => '']);
$this->_scanner->stdout('Removed empty elements - ' . $numberOfDeletetRows, Console::FG_RED);

$this->_scanner->stdout('Deleted language elements - END', Console::FG_RED);

return count($languageSourceIds);
Expand Down
53 changes: 47 additions & 6 deletions services/Scanner.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ class Scanner
*/
private $_languageElements = [];

/**
* @var array for storing updatable LanguageSource ids.
*/
private $_updatableLanguageSourceIds = [];

/**
* @var array for storing updated LanguageSource ids.
*/
private $_updatedLanguageSourceIds = [];

/**
* @var array for storing removabla LanguageSource ids.
*/
Expand Down Expand Up @@ -104,7 +114,17 @@ public function getNewLanguageElements()
*/
public function getRemovableLanguageSourceIds()
{
return $this->_removableLanguageSourceIds;
return array_diff_key($this->_removableLanguageSourceIds, $this->_updatableLanguageSourceIds);
}

/**
* Returns removable LanguageSource ids.
*
* @return array
*/
public function getUpdatedLanguageSourceIds()
{
return $this->_updatedLanguageSourceIds;
}

/**
Expand Down Expand Up @@ -133,7 +153,7 @@ private function _initLanguageArrays()
foreach ($languageSources as $languageSource) {
if (isset($this->_languageElements[$languageSource->category][$languageSource->message])) {
unset($this->_languageElements[$languageSource->category][$languageSource->message]);
} else {
} elseif(empty($this->_updatableLanguageSourceIds[$languageSource->id])) {
$this->_removableLanguageSourceIds[$languageSource->id] = $languageSource->id;
}
}
Expand All @@ -156,9 +176,29 @@ private function _scanningProject()
* @param string $category
* @param string $message
*/
public function addLanguageItem($category, $message)
public function addLanguageItem($category, $message, $sync_id = true)
{
$this->_languageElements[$category][$message] = true;
$updated = false;
if($sync_id !== true) {
$LanguageSource = LanguageSource::findOne(['sync_id' => $sync_id, 'category' => $category]);
if($LanguageSource) {
$updated = true;
if($LanguageSource->message !== $message) {
$LanguageSource->message = $message;
if($LanguageSource->save()) {
$this->_updatedLanguageSourceIds[$LanguageSource->id] = $LanguageSource->id;
foreach($LanguageSource->languageTranslates as $LanguageTranslate) {
$LanguageTranslate->status = 'pending';
$LanguageTranslate->save();
}
}
}
$this->_updatableLanguageSourceIds[$LanguageSource->id] = $LanguageSource->id;
}
}
if($sync_id === true || !$updated) {
$this->_languageElements[$category][$message] = $sync_id;
}

$coloredCategory = Console::ansiFormat($category, [Console::FG_YELLOW]);
$coloredMessage = Console::ansiFormat($message, [Console::FG_YELLOW]);
Expand All @@ -176,19 +216,20 @@ public function addLanguageItem($category, $message)
* [
* [
* 'category' => 'language',
* 'message' => 'Active'
* 'message' => 'Active',
* ],
* [
* 'category' => 'language',
* 'message' => 'Inactive'
* 'sync_id' => 'blog_title_8436',
* ],
* ]
* ~~~
*/
public function addLanguageItems($languageItems)
{
foreach ($languageItems as $languageItem) {
$this->addLanguageItem($languageItem['category'], $languageItem['message']);
$this->addLanguageItem($languageItem['category'], $languageItem['message'], $languageItem['sync_id'] ?? true);
}
}

Expand Down
22 changes: 17 additions & 5 deletions services/scanners/ScannerDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,27 @@ private function _scanningTable($tables)
{
$this->_scanner->stdout('Extracting mesages from ' . $tables['table'] . '.' . implode(',', $tables['columns']), Console::FG_GREEN);
$query = new \yii\db\Query();
$data = $query->select($tables['columns'])
$selectColumns = $tables['columns'];

if($tables['synchronize']) {
$pkFields = Yii::$app->{$tables['connection']}
->createCommand('SHOW INDEX FROM '.$tables['table'].' WHERE Key_name = \'PRIMARY\' ')->queryAll();
$pkFields = array_map(function ($e) {
return $e['Column_name'];
}, $pkFields);
$selectColumns = array_merge($pkFields, $selectColumns);
}

$data = $query->select($selectColumns)
->from($tables['table'])
->createCommand(Yii::$app->{$tables['connection']})
->queryAll();
$category = $this->_getCategory($tables);
foreach ($data as $columns) {
$columns = array_map('trim', $columns);
foreach ($columns as $column) {
$this->_scanner->addLanguageItem($category, $column);
foreach ($data as $dataRow) {
$dataRow = array_map('trim', $dataRow);
foreach ($tables['columns'] as $scanedColumn) {
$sync_id = $tables['synchronize'] ? implode('_', array_slice($dataRow, 0, sizeof($pkFields))).'_'.$scanedColumn : true;
$this->_scanner->addLanguageItem($category, $dataRow[$scanedColumn], $sync_id);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
*/

/* @var $this \yii\web\View */
/* @var $newDataProvider \yii\data\ArrayDataProvider */
/* @var $dataProvider \yii\data\ArrayDataProvider */

use yii\grid\GridView;

?>

<?php if ($newDataProvider->totalCount > 0) : ?>
<?php if ($dataProvider->totalCount > 0) : ?>

<?=

GridView::widget([
'id' => 'added-source',
'dataProvider' => $newDataProvider,
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'category',
Expand Down
Loading