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

Bootstrap 5 #152

Open
wants to merge 22 commits into
base: 1.7
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
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/).

## [Unreleased]

## [1.8.1] - 2020-07-04
### Fixed
- Fix `onlyCategories` option not applied correctly #135 (bjornhij)

## [1.8.0] - 2019-08-25

### Added
- Add `onlyCategories` option to Module settings #128

### Changed
- Improve TranslateBehavior saving #99
The attribute is now saved as translation when the language of the application is different from the source language.

## [1.7.3] - 2018-04-04
### Fixed
- Fix invalid column name in findOne() condition #118
Expand Down Expand Up @@ -80,11 +95,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/).
- Import/export feature #31

### Changed
- Autocofus translation textarea in frontend translation dialog #33
- Autofocus translation textarea in frontend translation dialog #33

### Fixed
- Round error in translation statistic

[Unreleased]: https://github.com/lajax/yii2-translate-manager/compare/1.8.1...HEAD
[1.8.1]: https://github.com/lajax/yii2-translate-manager/compare/1.8.0...1.8.1
[1.8.0]: https://github.com/lajax/yii2-translate-manager/compare/1.7.3...1.8.0
[1.7.3]: https://github.com/lajax/yii2-translate-manager/compare/1.7.2...1.7.3
[1.7.2]: https://github.com/lajax/yii2-translate-manager/compare/1.7.1...1.7.2
[1.7.1]: https://github.com/lajax/yii2-translate-manager/compare/1.7.0...1.7.1
Expand Down
20 changes: 19 additions & 1 deletion Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace lajax\translatemanager;

use Yii;
use yii\base\InvalidConfigException;
use yii\web\ForbiddenHttpException;
use yii\web\Response;

Expand Down Expand Up @@ -121,10 +122,15 @@ class Module extends \yii\base\Module
public $roles = [];

/**
* @var array list of the categories being ignored.
* @var string[] List of the categories being ignored.
*/
public $ignoredCategories = [];

/**
* @var string[] List of the categories to be scanned. If empty, all categories will be scanned.
*/
public $onlyCategories = [];

/**
* @var array directories/files being ignored.
*/
Expand Down Expand Up @@ -286,6 +292,18 @@ class Module extends \yii\base\Module
*/
public $scanners = [];

/**
* @throws InvalidConfigException
*/
public function init()
{
parent::init();

if ($this->onlyCategories && $this->ignoredCategories) {
throw new InvalidConfigException("Please configure either 'ignoredCategories', or 'onlyCategories'!");
}
}

/**
* @inheritdoc
*/
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ A more complex example including database table with multilingual support is bel
'jsTranslators' => ['lajax.t'], // list of the js function for translating messages.
'patterns' => ['*.js', '*.php'],// list of file extensions that contain language elements.
'ignoredCategories' => ['yii'], // these categories won't be included in the language database.
'onlyCategories' => ['yii'], // only these categories will be included in the language database (cannot be used together with "ignoredCategories").
'ignoredItems' => ['config'], // these files will not be processed.
'scanTimeLimit' => null, // increase to prevent "Maximum execution time" errors, if null the default max_execution_time will be used
'searchEmptyCommand' => '!', // the search string to enter in the 'Translation' search field to find not yet translated items, set to null to disable this feature
Expand Down Expand Up @@ -420,7 +421,17 @@ class Category extends \yii\db\ActiveRecord {

* With behavior (since 1.5.3):

**Note:** This will replace the model's original attribute values!
This behavior does the following:
- Replaces the specified attributes with translations after the model is loaded.
- Saves the attribute values as:
1. Source messages, if the current language is the source language.
2. Translations, if the current language is different from the source language.
This way the value stored in database is not overwritten with the translation.

**Note**: If the model should be saved as translation, but the source message does not exist yet in the database
then the message is saved as the source message whether the current language is the source language or not.
To avoid this scan the database for existing messages when using the behavior first, and only save new records
when the current language is the source language.

```php
namespace common\models;
Expand Down
96 changes: 86 additions & 10 deletions behaviors/TranslateBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,23 @@
use yii\db\BaseActiveRecord;
use yii\behaviors\AttributeBehavior;
use lajax\translatemanager\helpers\Language;
use lajax\translatemanager\models\LanguageSource;
use lajax\translatemanager\models\LanguageTranslate;

/**
* TranslateManager Database translate behavior.
* Behavior that translates the model attributes, and saves the changes into database.
*
* This behavior does the following:
* - Replaces the specified attributes with translations after the model is loaded.
* - Saves the attribute values as:
* 1. Source messages, if the current language is the source language.
* 2. Translations, if the current language is different from the source language.
* This way the value stored in database is not overwritten with the translation.
*
* **Note**: If the model should be saved as translation, but the source message does not exist yet in the database
* then the message is saved as the source message whether the current language is the source language or not.
* To avoid this scan the database for existing messages when using the behavior first, and only save new records
* when the current language is the source language.
*
* Installation:
*
Expand Down Expand Up @@ -45,6 +59,11 @@ class TranslateBehavior extends AttributeBehavior
*/
public $category = 'database';

/**
* @var BaseActiveRecord the owner model of this behavior
*/
public $owner;

/**
* @inheritdoc
*/
Expand All @@ -68,31 +87,88 @@ public function events()
}

/**
* Translates a message to the specified language.
* Translates the attributes to the current language.
*
* @param \yii\base\Event $event
*/
public function translateAttributes($event)
{
/* @var $owner BaseActiveRecord */
$owner = $this->owner;
foreach ($this->translateAttributes as $attribute) {
$owner->{$attribute} = Yii::t($this->category, $owner->attributes[$attribute]);
$this->owner->{$attribute} = Yii::t($this->category, $this->owner->attributes[$attribute]);
}
}

/**
* Saveing new language element by category.
* Saves new language element by category.
*
* @param \yii\base\Event $event
*/
public function saveAttributes($event)
{
/* @var $owner BaseActiveRecord */
$owner = $this->owner;
$isAppInSourceLanguage = Yii::$app->sourceLanguage === Yii::$app->language;

foreach ($this->translateAttributes as $attribute) {
if ($owner->isAttributeChanged($attribute)) {
Language::saveMessage($owner->attributes[$attribute], $this->category);
if (!$this->owner->isAttributeChanged($attribute)) {
continue;
}

if ($isAppInSourceLanguage || !$this->saveAttributeValueAsTranslation($attribute)) {
Language::saveMessage($this->owner->attributes[$attribute], $this->category);
}
}
}

/**
* @param string $attribute The name of the attribute.
*
* @return bool Whether the translation is saved.
*/
private function saveAttributeValueAsTranslation($attribute)
{
$sourceMessage = $this->owner->getOldAttribute($attribute);
$translatedMessage = $this->owner->attributes[$attribute];

// Restore the original value, so it won't be replaced with the translation in the database.
$this->owner->{$attribute} = $sourceMessage;

$translateSource = $this->findSourceMessage($sourceMessage);
if (!$translateSource) {
return false; // The source does not exist, the message cannot be saved as translation.
}

$translation = new LanguageTranslate();
foreach ($translateSource->languageTranslates as $tmpTranslate) {
if ($tmpTranslate->language === Yii::$app->language) {
$translation = $tmpTranslate;
break;
}
}

if ($translation->isNewRecord) {
$translation->id = $translateSource->id;
$translation->language = Yii::$app->language;
}

$translation->translation = $translatedMessage;
$translation->save();

return true;
}

/**
* Finds the source record with case sensitive match.
*
* @param string $message
*
* @return LanguageSource|null Null if the source is not found.
*/
private function findSourceMessage($message)
{
$sourceMessages = LanguageSource::findAll(['message' => $message, 'category' => $this->category]);

foreach ($sourceMessages as $source) {
if ($source->message === $message) {
return $source;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lajax/yii2-translate-manager",
"description": "Online Translate",
"description": "Translation management extension for Yii 2",
"type": "yii2-extension",
"keywords": ["yii2", "extension", "translate", "language", "module"],
"license": "MIT",
Expand Down
10 changes: 9 additions & 1 deletion services/scanners/ScannerFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,14 @@ private function _getRoots()
*/
protected function isValidCategory($category)
{
return !in_array($category, $this->module->ignoredCategories);
if ($this->module->onlyCategories) {
return in_array($category, $this->module->onlyCategories);
}

if ($this->module->ignoredCategories) {
return !in_array($category, $this->module->ignoredCategories);
}

return true;
}
}