From a4c24899b6b419a47d8a542b15312027abf2737b Mon Sep 17 00:00:00 2001 From: guga Date: Tue, 17 Jan 2017 10:08:41 +0400 Subject: [PATCH] i18n integration --- controllers/I18nController.php | 57 +++++++++++++++++++++++ models/I18nSourceMessage.php | 59 ++++++++++++++++++++++- models/search/I18nSearch.php | 68 +++++++++++++++++++++++++++ views/i18n/_form.php | 85 ++++++++++++++++++++++++++++++++++ views/i18n/_tab_content.php | 17 +++++++ views/i18n/create.php | 19 ++++++++ views/i18n/index.php | 50 ++++++++++++++++++++ 7 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 models/search/I18nSearch.php create mode 100644 views/i18n/_form.php create mode 100644 views/i18n/_tab_content.php create mode 100644 views/i18n/create.php create mode 100644 views/i18n/index.php diff --git a/controllers/I18nController.php b/controllers/I18nController.php index 58b0bdf..7dff8db 100644 --- a/controllers/I18nController.php +++ b/controllers/I18nController.php @@ -9,8 +9,15 @@ namespace centigen\i18ncontent\controllers; +use centigen\i18ncontent\helpers\BaseHelper; +use centigen\i18ncontent\models\I18nMessage; +use centigen\i18ncontent\models\I18nSourceMessage; +use centigen\i18ncontent\models\search\I18nSearch; use centigen\i18ncontent\web\Controller; +use Yii; use yii\filters\VerbFilter; +use yii\helpers\ArrayHelper; +use yii\helpers\Url; class I18nController extends Controller { @@ -27,4 +34,54 @@ public function behaviors() ]; } + + /** + * Lists all I18nMessage models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new I18nSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + Url::remember(Yii::$app->request->getUrl(), 'i18n-messages-filter'); + + $languages = ArrayHelper::map( + I18nMessage::find()->select('language')->distinct()->all(), + 'language', + 'language' + ); + $categories = ArrayHelper::map( + I18nSourceMessage::find()->select('category')->distinct()->all(), + 'category', + 'category' + ); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'languages' => $languages, + 'categories' => $categories + ]); + } + + /** + * Creates a new Article model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new I18nSourceMessage(); + + $locales = BaseHelper::getAvailableLocales(); + + if ($model->load(Yii::$app->request->post(), null) && $model->save()) { + return $this->redirect(['index']); + } + return $this->render('create', [ + 'model' => $model, + 'locales' => $locales + ]); + } + } \ No newline at end of file diff --git a/models/I18nSourceMessage.php b/models/I18nSourceMessage.php index 3bc2fea..61ca178 100644 --- a/models/I18nSourceMessage.php +++ b/models/I18nSourceMessage.php @@ -3,6 +3,9 @@ namespace centigen\i18ncontent\models; use Yii; +use yii\db\ActiveRecord; +use yii\helpers\ArrayHelper; +use yii\helpers\StringHelper; /** * This is the model class for table "{{%i18n_source_message}}". @@ -12,9 +15,11 @@ * @property string $message * * @property I18nMessage[] $i18nMessages + * @property ActiveRecord[]|array $translations */ -class I18nSourceMessage extends \yii\db\ActiveRecord +class I18nSourceMessage extends ActiveRecord { + public $newTranslations = []; /** * @inheritdoc */ @@ -53,4 +58,56 @@ public function getI18nMessages() { return $this->hasMany(I18nMessage::className(), ['id' => 'id']); } + + + /** + * @author Guga Grigolia + * @inheritdoc + */ + public function load($postData, $formName = null) + { + if (!parent::load($postData, $formName)) { + return false; + } + + $className = StringHelper::basename(I18nMessage::className()); + $translations = ArrayHelper::getValue($postData, $className); + $this->newTranslations = []; + + $allValid = true; + if(!empty($translations)){ + foreach ($translations as $loc => $modelData) { + $modelData['language'] = $loc; + + + $translation = $this->findTranslationByLocale($loc); + + $this->newTranslations[] = $translation; + if (!$translation->load($modelData, '')) { + $allValid = false; + } + } + } + + return $allValid; + } + + /** + * Find PageTranslation object from `translations` array by locale + * + * @author Guga Grigolia + * @param $locale + * @return ActiveRecord + */ + public function findTranslationByLocale($locale) + { + $translations = array_merge($this->newTranslations, $this->i18nMessages); + foreach ($translations as $translation) { + if ($translation->locale === $locale) { + return $translation; + } + } + + return new I18nMessage(); + } } diff --git a/models/search/I18nSearch.php b/models/search/I18nSearch.php new file mode 100644 index 0000000..a897d42 --- /dev/null +++ b/models/search/I18nSearch.php @@ -0,0 +1,68 @@ +with('sourceMessageModel')->joinWith('sourceMessageModel'); + + $dataProvider = new ActiveDataProvider([ + 'query' => $query + ]); + + if (!($this->load($params) && $this->validate())) { + return $dataProvider; + } + + + + $query->andFilterWhere([ + '{{%i18n_source_message}}.id' => $this->id + ]); + + $query->andFilterWhere(['like', '{{%i18n_message}}.language', $this->language]) + ->andFilterWhere(['like', '{{%i18n_message}}.translation', $this->translation]) + ->andFilterWhere(['like', '{{%i18n_source_message}}.message', $this->sourceMessage]) + ->andFilterWhere(['like', '{{%i18n_source_message}}.category', $this->category]); + + + return $dataProvider; + } +} diff --git a/views/i18n/_form.php b/views/i18n/_form.php new file mode 100644 index 0000000..8e00226 --- /dev/null +++ b/views/i18n/_form.php @@ -0,0 +1,85 @@ + + +
+ + + + field($model, 'category')->textInput(['maxlength' => 32]) ?> + + field($model, 'message')->textarea(['rows' => 6]) ?> + + + $locale) { + $title = $locale; + $translationModel = $model->findTranslationByLocale($key); + + $content = $this->render('_tab_content', [ + 'form' => $form, + 'model' => $translationModel, + 'language' => $key, + ]); + + $items[] = [ + 'label' => $title, + 'content' => $content, + 'headerOptions' => [ + 'title' => $translationModel->hasErrors() ? Yii::t('i18ncontent', 'You have validation errors') : "", + 'class' => $translationModel->hasErrors() ? 'has-error' : '', + 'data-toggle' => 'tooltip' + ], + 'options' => [ + 'class' => 'fade' . ($ind++ === 0 ? ' in' : '') + ] + ]; + } + echo '
'; + echo Tabs::widget([ + 'items' => $items + ]); + echo '
'; + } else { + echo $this->render('_tab_content', [ + 'form' => $form, + 'model' => $model + ]); + } + + ?> + + +
+ isNewRecord ? Yii::t('i18ncontent', 'Create') : Yii::t('i18ncontent', 'Update'), + ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> +
+ + + + isNewRecord): ?> +
+ $model->id], + [ + 'class' => 'btn btn-danger', + 'data-confirm' => "Are you sure you want to delete this item?", + 'data-method'=>"post", + 'data-pjax' => "0" + ]) ?> +
+ +
diff --git a/views/i18n/_tab_content.php b/views/i18n/_tab_content.php new file mode 100644 index 0000000..d67fdf5 --- /dev/null +++ b/views/i18n/_tab_content.php @@ -0,0 +1,17 @@ + +field($model, 'translation', [ + 'inputOptions' => [ + 'name' => "{$className}[$language][translation]" + ] +])->textarea(['maxlength' => 512]) ?> diff --git a/views/i18n/create.php b/views/i18n/create.php new file mode 100644 index 0000000..1d4b156 --- /dev/null +++ b/views/i18n/create.php @@ -0,0 +1,19 @@ +title = Yii::t('i18ncontent', 'Create {modelClass}', [ + 'modelClass' => 'i18n', +]); +$this->params['breadcrumbs'][] = ['label' => Yii::t('i18ncontent', 'i18n'), 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + 'locales' => $locales + ]) ?> + +
diff --git a/views/i18n/index.php b/views/i18n/index.php new file mode 100644 index 0000000..2133c9b --- /dev/null +++ b/views/i18n/index.php @@ -0,0 +1,50 @@ +title = Yii::t('backend', 'I18n Messages'); +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_search', ['model' => $searchModel]); ?> + +

+ 'I18n Message', +]), ['create'], ['class' => 'btn btn-success']) ?> +

+ + $dataProvider, + 'filterModel' => $searchModel, + 'options' => [ + 'class' => 'grid-view table-responsive' + ], + 'columns' => [ + + 'id', + [ + 'attribute'=>'language', + 'filter'=> $languages + ], + [ + 'attribute'=>'category', + 'filter'=> $categories + ], + 'sourceMessage', + 'translation:ntext', + ['class' => 'yii\grid\ActionColumn', 'template'=>'{update} {delete}'], + ], + ]); ?> + +
\ No newline at end of file