Browse Source

Settings languages

master
Egorka 6 years ago
parent
commit
3a3e813cbe
  1. 82
      backend/bootstrap/SetUp.php
  2. 28
      backend/controllers/settings/ListController.php
  3. 107
      backend/forms/SettingsSearch.php
  4. 82
      backend/messages/ru/main.php
  5. 81
      backend/views/layouts/header.php
  6. 68
      backend/views/settings/list/_form.php
  7. 16
      backend/views/settings/list/_form_tab.php
  8. 26
      backend/views/settings/list/_view_tab.php
  9. 111
      backend/views/settings/list/index.php
  10. 23
      backend/views/settings/list/update.php
  11. 112
      backend/views/settings/list/view.php
  12. 110
      common/modules/pages/forms/PageForm.php
  13. 153
      common/modules/pages/views/manage/page/_form.php
  14. 192
      common/modules/pages/views/manage/page/view.php
  15. 42
      console/migrations/m180604_124108_create_settings_table.php
  16. 28
      console/migrations/m180824_081717_create_menu_lng_table.php
  17. 14
      console/migrations/m180827_194913_set_core_tables_unicode_oollate.php
  18. 50
      console/migrations/m180910_182109_create_settings_lng_table.php
  19. 78
      core/behaviors/LanguageBehavior.php
  20. 24
      core/entities/Settings.php
  21. 229
      core/forms/SettingsForm.php
  22. 6
      core/repositories/SettingsRepository.php
  23. 12
      core/services/SettingsService.php

82
backend/bootstrap/SetUp.php

@ -16,45 +16,59 @@ class SetUp implements BootstrapInterface
$container = \Yii::$container; $container = \Yii::$container;
// init presets // init presets
$presetsPath = \Yii::getAlias('@core/components/ckeditor/presets'); $presetsPath = \Yii::getAlias('@core/components/ckeditor/presets');
// basic // basic
$app->params['ckeditor']['basic']['toolbar'] = require $presetsPath . '/basic/toolbar.php'; $app->params['ckeditor']['basic']['toolbar'] = require $presetsPath . '/basic/toolbar.php';
$app->params['ckeditor']['basic']['plugins'] = require $presetsPath . '/basic/plugins.php'; $app->params['ckeditor']['basic']['plugins'] = require $presetsPath . '/basic/plugins.php';
// editor // editor
$app->params['ckeditor']['editor']['toolbar'] = require $presetsPath . '/editor/toolbar.php'; $app->params['ckeditor']['editor']['toolbar'] = require $presetsPath . '/editor/toolbar.php';
$app->params['ckeditor']['editor']['plugins'] = require $presetsPath . '/editor/plugins.php'; $app->params['ckeditor']['editor']['plugins'] = require $presetsPath . '/editor/plugins.php';
// debeloper // debeloper
$app->params['ckeditor']['developer']['toolbar'] = require $presetsPath . '/developer/toolbar.php'; $app->params['ckeditor']['developer']['toolbar'] = require $presetsPath . '/developer/toolbar.php';
$app->params['ckeditor']['developer']['plugins'] = require $presetsPath . '/developer/plugins.php'; $app->params['ckeditor']['developer']['plugins'] = require $presetsPath . '/developer/plugins.php';
// set preset example // set preset example
/*$form->field($model, 'content')->widget(CKEditor::class, [ /*$form->field($model, 'content')->widget(CKEditor::class, [
'editorOptions' => \zertex\elfinder\ElFinder::ckeditorOptions('elfinder',[ 'editorOptions' => \zertex\elfinder\ElFinder::ckeditorOptions('elfinder',[
'toolbar' => Yii::$app->params['ckeditor']['editor']['toolbar'], 'toolbar' => Yii::$app->params['ckeditor']['editor']['toolbar'],
'extraPlugins' => Yii::$app->params['ckeditor']['editor']['plugins'], 'extraPlugins' => Yii::$app->params['ckeditor']['editor']['plugins'],
]) ])
])*/ ])*/
$container->set(CKEditor::class, [ $container->set(CKEditor::class, [
'editorOptions' => ElFinder::ckeditorOptions('elfinder', [ 'editorOptions' => ElFinder::ckeditorOptions('elfinder', [
'toolbar' => $app->params['ckeditor']['editor']['toolbar'], 'toolbar' => $app->params['ckeditor']['editor']['toolbar'],
'extraPlugins' => $app->params['ckeditor']['editor']['plugins'], 'extraPlugins' => $app->params['ckeditor']['editor']['plugins'],
'language' => $app->language, 'language' => $app->language,
]), ]),
]); ]);
// load settings // load settings
$settings = ArrayHelper::map(Settings::find()->andWhere(['active' => 1])->all(), 'key', 'value', 'section'); $settings = Settings::find()->with('translations')->andWhere(['active' => 1])->all();
$app->params['settings'] = $settings; //$settings = Settings::find()->andWhere(['active' => 1])->all();
//$settings_array = [];
// Connect backend modules /*foreach ($settings as $setting) {
if (!isset($settings_array[$setting->section])) {
// Add finish UrlRules $settings_array[$setting->section] = [];
$app->getUrlManager()->addRules([ }
'<_c:[\w\-]+>' => '<_c>/index', //$settings_array[$setting->section][$setting->key] = $setting->translation->value;
'<_c:[\w\-]+>/<id:\d+>' => '<_c>/view', }*/
'<_c:[\w\-]+>/<_a:[\w-]+>' => '<_c>/<_a>',
'<_c:[\w\-]+>/<id:\d+>/<_a:[\w\-]+>' => '<_c>/<_a>', $settings_array = $settings ? ArrayHelper::map($settings, 'key', function ($el) {
]); return $el->translation->value;
}, 'section') : [];
//$settings = ArrayHelper::map(Settings::find()->andWhere(['active' => 1])->all(), 'key', 'value', 'section');
$app->params['settings'] = $settings_array;
// Connect backend modules
// Add finish UrlRules
$app->getUrlManager()->addRules([
'<_c:[\w\-]+>' => '<_c>/index',
'<_c:[\w\-]+>/<id:\d+>' => '<_c>/view',
'<_c:[\w\-]+>/<_a:[\w-]+>' => '<_c>/<_a>',
'<_c:[\w\-]+>/<id:\d+>/<_a:[\w\-]+>' => '<_c>/<_a>',
]);
} }
} }

28
backend/controllers/settings/ListController.php

@ -64,9 +64,10 @@ class ListController extends Controller
]; ];
} }
public function actionIndex() public function actionIndex($section = 'site')
{ {
$searchModel = new SettingsSearch(); $searchModel = new SettingsSearch();
$searchModel->section = $section;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render( return $this->render(
@ -74,16 +75,17 @@ class ListController extends Controller
[ [
'searchModel' => $searchModel, 'searchModel' => $searchModel,
'dataProvider' => $dataProvider, 'dataProvider' => $dataProvider,
'section' => $section,
] ]
); );
} }
public function actionView($id) public function actionView($section, $key)
{ {
return $this->render( return $this->render(
'view', 'view',
[ [
'model' => $this->findModel($id), 'model' => $this->findModel($section, $key),
] ]
); );
} }
@ -95,7 +97,7 @@ class ListController extends Controller
try { try {
$settings = $this->_service->create($form); $settings = $this->_service->create($form);
return $this->redirect(['view', 'id' => $settings->id]); return $this->redirect(['view', 'section' => $settings->section, 'key' => $settings->key]);
} catch (\DomainException $e) { } catch (\DomainException $e) {
Yii::$app->errorHandler->logException($e); Yii::$app->errorHandler->logException($e);
Yii::$app->session->setFlash('error', $e->getMessage()); Yii::$app->session->setFlash('error', $e->getMessage());
@ -112,16 +114,16 @@ class ListController extends Controller
); );
} }
public function actionUpdate($id) public function actionUpdate($section, $key)
{ {
$settings = $this->findModel($id); $settings = $this->findModel($section, $key);
$form = new SettingsForm($settings); $form = new SettingsForm($settings);
if ($form->load(Yii::$app->request->post()) && $form->validate()) { if ($form->load(Yii::$app->request->post()) && $form->validate()) {
try { try {
$this->_service->edit($settings->id, $form); $this->_service->edit($settings->section, $settings->key, $form);
return $this->redirect(['view', 'id' => $settings->id]); return $this->redirect(['view', 'section' => $settings->section, 'key' => $settings->key]);
} catch (\DomainException $e) { } catch (\DomainException $e) {
Yii::$app->errorHandler->logException($e); Yii::$app->errorHandler->logException($e);
Yii::$app->session->setFlash('error', $e->getMessage()); Yii::$app->session->setFlash('error', $e->getMessage());
@ -137,19 +139,19 @@ class ListController extends Controller
); );
} }
public function actionDelete($id) public function actionDelete($section, $key)
{ {
$this->_service->remove($id); $this->_service->remove($section, $key);
return $this->redirect(['index']); return $this->redirect(['index']);
} }
protected function findModel($id) protected function findModel($section, $key)
{ {
if (($model = Settings::findOne($id)) !== null) { if (($model = Settings::find()->andWhere(['section' => $section])->andWhere(['key' => $key])->one()) !== null) {
return $model; return $model;
} else { } else {
throw new NotFoundHttpException('The requested page does not exist.'); throw new NotFoundHttpException('The requested setting does not exist.');
} }
} }
} }

107
backend/forms/SettingsSearch.php

@ -6,61 +6,68 @@
namespace backend\forms; namespace backend\forms;
use core\entities\Settings; use core\entities\Settings;
use yii\base\Model; use yii\base\Model;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
class SettingsSearch extends Settings class SettingsSearch extends Settings
{ {
public $id; public $id;
public $type; public $type;
public $section; public $section;
public $key; public $key;
public $value; public $value;
public $active; public $active;
public function rules()
{
return [
[['id'], 'integer'],
[['active'], 'boolean'],
[['type', 'section', 'key', 'value'], 'safe'],
];
}
/**
* @return array
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
public function rules() /**
{ * @param $params
return [ *
[['id'], 'integer'], * @return ActiveDataProvider
[['active'], 'boolean'], */
[['type', 'section', 'key', 'value'], 'safe'], public function search($params)
]; {
} $query = Settings::find();
/** $dataProvider = new ActiveDataProvider(
* @return array [
*/ 'query' => $query,
public function scenarios() ]
{ );
// bypass scenarios() implementation in the parent class if (!($this->load($params) && $this->validate())) {
return Model::scenarios(); $query->andFilterWhere(
} [
/** 'section' => $this->section,
* @param $params ]
* @return ActiveDataProvider );
*/ return $dataProvider;
public function search($params) }
{ $query->andFilterWhere(
$query = Settings::find(); [
$dataProvider = new ActiveDataProvider( 'id' => $this->id,
[ 'active' => $this->active,
'query' => $query, 'section' => $this->section,
] ]
); );
if (!($this->load($params) && $this->validate())) { $query->andFilterWhere(['like', 'key', $this->key])
return $dataProvider; ->andFilterWhere(['like', 'value', $this->value]);
}
$query->andFilterWhere(
[
'id' => $this->id,
'active' => $this->active,
'section' => $this->section,
]
);
$query->andFilterWhere(['like', 'key', $this->key])
->andFilterWhere(['like', 'value', $this->value]);
return $dataProvider;
}
} return $dataProvider;
}
}

82
backend/messages/ru/main.php

@ -1,42 +1,44 @@
<?php <?php
return [ return [
'Menu' => 'Меню', 'Menu' => 'Меню',
'Title' => 'Заголовок', 'Title' => 'Заголовок',
'Description' => 'Описание', 'Description' => 'Описание',
'Keywords' => 'Ключевые слова', 'Keywords' => 'Ключевые слова',
'Sign out' => 'Выход', 'Sign out' => 'Выход',
'Profile' => 'Профиль', 'Profile' => 'Профиль',
'Error' => 'Ошибка', 'Error' => 'Ошибка',
'Return to back or login page please.' => 'Вернитесь назад или авторизуйтесь снова.', 'Return to back or login page please.' => 'Вернитесь назад или авторизуйтесь снова.',
'{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" уже есть в этом разделе.', '{attribute} "{value}" already exists for this section.' => '{attribute} "{value}" уже есть в этом разделе.',
'"{attribute}" must be a valid JSON object' => '"{attribute}" должен быть в формате Json', '"{attribute}" must be a valid JSON object' => '"{attribute}" должен быть в формате Json',
'Please select correct type' => 'Укажите правильный тип', 'Please select correct type' => 'Укажите правильный тип',
'Settings' => 'Настройки', 'Settings' => 'Настройки',
'Type' => 'Тип', 'Type' => 'Тип',
'Section' => 'Раздел', 'Section' => 'Раздел',
'Key' => 'Ключ', 'Key' => 'Ключ',
'Value' => 'Значение', 'Value' => 'Значение',
'Active' => 'Активная', 'Active' => 'Активная',
'Created At' => 'Создано', 'Created At' => 'Создано',
'Updated At' => 'Обновлено', 'Updated At' => 'Обновлено',
'On' => 'Включить', 'On' => 'Включить',
'Off' => 'Выключить', 'Off' => 'Выключить',
'Updating Setting' => 'Редактирование параметра', 'Updating Setting' => 'Редактирование параметра',
'Editing' => 'Редактирование', 'Editing' => 'Редактирование',
'Change at your own risk' => 'Редактируйте на свой страх и риск', 'Change at your own risk' => 'Редактируйте на свой страх и риск',
'Online' => 'В сети', 'Online' => 'В сети',
'Search results' => 'Поиск', 'Search results' => 'Поиск',
'Search...' => 'Поиск...', 'Search...' => 'Поиск...',
'Name' => 'Название', 'Name' => 'Название',
'Title attribute' => 'Атрибут тега Title', 'Title attribute' => 'Атрибут тега Title',
'Url' => 'Ссылка', 'Url' => 'Ссылка',
'Sign in to start your session' => 'Вход в панель управления', 'Sign in to start your session' => 'Вход в панель управления',
'You have {count} notifications' => 'Новых уведомлений: {count}', 'You have {count} notifications' => 'Новых уведомлений: {count}',
'Modules' => 'Модули', 'Modules' => 'Модули',
'Find modules' => 'Поиск модулей', 'Find modules' => 'Поиск модулей',
'Enable' => 'Включить', 'Enable' => 'Включить',
'Disable' => 'Отключить', 'Disable' => 'Отключить',
'Settings List' => 'Все настройки', 'Settings List' => 'Все настройки',
'Create Setting' => 'Новый параметр', 'Create Setting' => 'Новый параметр',
'Interface Language' => 'Язык интерфейса', 'Interface Language' => 'Язык интерфейса',
]; 'design' => 'Оформление',
'site' => 'Сайт',
];

81
backend/views/layouts/header.php

@ -1,6 +1,6 @@
<?php <?php
use yii\helpers\Html; use yii\helpers\Html;
use core\components\avatar_generator\AvatarGenerator;
/* @var $this \yii\web\View */ /* @var $this \yii\web\View */
/* @var $content string */ /* @var $content string */
@ -10,7 +10,7 @@ use core\components\avatar_generator\AvatarGenerator;
<header class="main-header"> <header class="main-header">
<?= Html::a('<span class="logo-mini">'.(isset(Yii::$app->params['settings']['site']['short_name']) ? Yii::$app->params['settings']['site']['short_name'] : 'APP').'</span><span class="logo-lg">' . (isset(Yii::$app->params['settings']['site']['name']) ? Yii::$app->params['settings']['site']['name'] : Yii::$app->name) . '</span>', Yii::$app->homeUrl, ['class' => 'logo']) ?> <?= Html::a('<span class="logo-mini">' . (isset(Yii::$app->params['settings']['site']['short_name']) ? Yii::$app->params['settings']['site']['short_name'] : 'APP') . '</span><span class="logo-lg">' . (isset(Yii::$app->params['settings']['site']['name']) ? Yii::$app->params['settings']['site']['name'] : Yii::$app->name) . '</span>', Yii::$app->homeUrl, ['class' => 'logo']) ?>
<nav class="navbar navbar-static-top" role="navigation"> <nav class="navbar navbar-static-top" role="navigation">
@ -23,7 +23,7 @@ use core\components\avatar_generator\AvatarGenerator;
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<!-- Messages: style can be found in dropdown.less--> <!-- Messages: style can be found in dropdown.less-->
<!-- <!--
<li class="dropdown messages-menu"> <li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-envelope-o"></i> <i class="fa fa-envelope-o"></i>
@ -105,12 +105,12 @@ use core\components\avatar_generator\AvatarGenerator;
<li class="footer"><a href="#">See All Messages</a></li> <li class="footer"><a href="#">See All Messages</a></li>
</ul> </ul>
</li> </li>
--> -->
<?= \backend\widgets\NotificationCountWidget::widget() ?> <?= \backend\widgets\NotificationCountWidget::widget() ?>
<!-- Tasks: style can be found in dropdown.less --> <!-- Tasks: style can be found in dropdown.less -->
<!-- <!--
<li class="dropdown tasks-menu"> <li class="dropdown tasks-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-flag-o"></i> <i class="fa fa-flag-o"></i>
@ -191,55 +191,60 @@ use core\components\avatar_generator\AvatarGenerator;
</li> </li>
</ul> </ul>
</li> </li>
--> -->
<!-- Language Drop Down --> <!-- Language Drop Down -->
<li class="dropdown messages-menu"> <li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<!-- <i class="fa fa-language"></i> --> <!-- <i class="fa fa-language"></i> -->
<span><?= \core\helpers\LanguageHelper::getBackendName(Yii::$app->user->identity->user->backend_language) ?> <i class="caret"></i></span> <span><?= \core\helpers\LanguageHelper::getBackendName(Yii::$app->user->identity->user->backend_language) ?>
</a> <i class="caret"></i></span>
<ul class="dropdown-menu"> </a>
<li class="header"><?= Yii::t('main', 'Interface Language') ?></li> <ul class="dropdown-menu">
<li> <li class="header"><?= Yii::t('main', 'Interface Language') ?></li>
<!-- inner menu: contains the actual data --> <li>
<ul class="menu"> <!-- inner menu: contains the actual data -->
<?php foreach (Yii::$app->params['backendTranslatedLanguages'] as $language => $language_name): ?> <ul class="menu">
<li> <?php foreach (Yii::$app->params['backendTranslatedLanguages'] as $language => $language_name): ?>
<?= Html::a($language_name, ['/site/language', 'language' => $language], [ <li>
'data-method' => 'post' <?= Html::a($language_name, ['/site/language', 'language' => $language], [
]) ?> 'data-method' => 'post'
</li> ]) ?>
<?php endforeach; ?> </li>
</ul> <?php endforeach; ?>
</li> </ul>
</ul> </li>
</li> </ul>
</li>
<li class="dropdown user user-menu"> <li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="<?= Yii::$app->avatar->show(Yii::$app->user->identity->user->username) ?>" class="user-image" alt="<?= Yii::$app->user->identity->user->username ?>"/> <img src="<?= Yii::$app->avatar->show(Yii::$app->user->identity->user->username) ?>"
class="user-image" alt="<?= Yii::$app->user->identity->user->username ?>"/>
<span class="hidden-xs"><?= Yii::$app->user->identity->user->username ?></span> <span class="hidden-xs"><?= Yii::$app->user->identity->user->username ?></span>
</a> </a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<!-- User image --> <!-- User image -->
<li class="user-header"> <li class="user-header">
<img src="<?= Yii::$app->avatar->show(Yii::$app->user->identity->user->username) ?>" class="img-circle" <img src="<?= Yii::$app->avatar->show(Yii::$app->user->identity->user->username) ?>"
class="img-circle"
alt="<?= Yii::$app->user->identity->user->username ?>"/> alt="<?= Yii::$app->user->identity->user->username ?>"/>
<p> <p>
<?= Yii::$app->user->identity->user->username ?> <?= Yii::$app->user->identity->user->username ?>
<small><?= Yii::t('user', 'Registered: {date}', ['date' => date('d.m.Y', Yii::$app->user->identity->user->created_at)]) ?></small> <small><?= Yii::t('user', 'Registered: {date}', [
'date' => date('d.m.Y', Yii::$app->user->identity->user->created_at)
]) ?></small>
</p> </p>
</li> </li>
<!-- Menu Footer--> <!-- Menu Footer-->
<li class="user-footer"> <li class="user-footer">
<div class="pull-left"> <div class="pull-left">
<?= Html::a( <?= Html::a(
Yii::t('user', 'Profile'), Yii::t('user', 'Profile'),
['/user/profile'], ['/user/profile'],
['class' => 'btn btn-default btn-flat'] ['class' => 'btn btn-default btn-flat']
) ?> ) ?>
</div> </div>
<div class="pull-right"> <div class="pull-right">
<?= Html::a( <?= Html::a(

68
backend/views/settings/list/_form.php

@ -9,35 +9,69 @@ use core\forms\SettingsForm;
* @var SettingsForm $model * @var SettingsForm $model
* @var yii\widgets\ActiveForm $form * @var yii\widgets\ActiveForm $form
*/ */
$js2 = '
$(".hint-block").each(function () {
var $hint = $(this);
var label = $hint.parent().find("label");
label.html(label.html() + \' <i style="color:#3c8dbc" class="fa fa-question-circle" aria-hidden="true"></i>\');
label.addClass("help").popover({
html: true,
trigger: "hover",
placement: "bottom",
content: $hint.html()
});
$(this).hide();
});
';
$this->registerJs($js2);
?> ?>
<div class="setting-form"> <div class="setting-form">
<div class="box box-default"> <div class="box box-default">
<div class="box-body"> <div class="box-body">
<?php $form = ActiveForm::begin(); ?>
<?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'section')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'section')->textInput(['maxlength' => 255]) ?> <?= $form->field($model, 'key')->textInput(['maxlength' => 255]) ?>
<?= $form->field($model, 'key')->textInput(['maxlength' => 255]) ?> <?= $form->field($model, 'active')->checkbox(['value' => 1]) ?>
<?= $form->field($model, 'value')->textarea(['rows' => 6]) ?> <?=
$form->field($model, 'type')->dropDownList(
$model->getTypes()
)->hint(Yii::t('main', 'Change at your own risk')) ?>
<?= $form->field($model, 'active')->checkbox(['value' => 1]) ?> <?php
$items = [];
foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) {
$items[] = [
'label' => $language_name,
'content' => $this->render('_form_tab', [
'form' => $form,
'model' => $model,
'language' => $language,
]),
];
}
?>
<?= <div class="nav-tabs-custom">
$form->field($model, 'type')->dropDownList( <?= \yii\bootstrap\Tabs::widget([
$model->getTypes() 'items' => $items
)->hint(Yii::t('main', 'Change at your own risk')) ?> ]) ?>
</div>
<div class="form-group"> <div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?> <?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
</div> </div>
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
</div> </div>
</div> </div>
</div> </div>

16
backend/views/settings/list/_form_tab.php

@ -0,0 +1,16 @@
<?php
/**
* Created by Error202
* Date: 24.08.2018
*/
/**
* @var $this \yii\web\View
* @var $form \yii\widgets\ActiveForm
* @var $model \core\forms\SettingsForm
* @var $language string
*/
$postfix = $language == Yii::$app->params['defaultLanguage'] ? '' : '_' . $language;
echo $form->field($model, 'value' . $postfix)->textarea(['rows' => 6]);

26
backend/views/settings/list/_view_tab.php

@ -0,0 +1,26 @@
<?php
/**
* Created by Error202
* Date: 25.08.2018
*/
use yii\widgets\DetailView;
use core\entities\Settings;
/**
* @var $this \yii\web\View
* @var $setting Settings
* @var $language string
*/
echo DetailView::widget([
'model' => $setting,
'attributes' => [
[
'label' => Yii::t('main', 'Value'),
'value' => function (Settings $entity) use ($language) {
return $entity->findTranslation($language)->value;
}
],
],
]);

111
backend/views/settings/list/index.php

@ -11,60 +11,75 @@ use backend\components\ToggleColumn;
* @var yii\web\View $this * @var yii\web\View $this
* @var \backend\forms\SettingsSearch $searchModel * @var \backend\forms\SettingsSearch $searchModel
* @var yii\data\ActiveDataProvider $dataProvider * @var yii\data\ActiveDataProvider $dataProvider
* @var string $section
*/ */
$this->title = Yii::t('main', 'Settings'); $this->title = Yii::t('main', 'Settings');
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
?> ?>
<div class="setting-index"> <div class="setting-index">
<p> <p>
<?= <?=
Html::a( Html::a(
Yii::t('buttons','Create Setting'), Yii::t('buttons', 'Create Setting'),
['create'], ['create'],
['class' => 'btn btn-success'] ['class' => 'btn btn-success']
) ?> ) ?>
</p> </p>
<div class="box"> <div class="row">
<div class="box-body"> <div class="col-md-3">
<div class="list-group">
<?php foreach (Settings::find()->select('section')->distinct()->where(['<>', 'section', ''])->all() as $setting) : ?>
<?= Html::a(Yii::t('main', $setting->section), ['/settings/list/index', 'section' => $setting->section], [
'class' => 'list-group-item ' . ($section == $setting->section ? 'active' : ''),
]) ?>
<?php endforeach; ?>
</div>
</div>
<div class="col-md-9">
<div class="box">
<div class="box-body">
<?php Pjax::begin(); ?>
<?=
GridView::widget(
[
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'attribute' => 'key',
'options' => ['style' => 'width: 25%;'],
],
[
'label' => Yii::t('main', 'Value'),
'value' => function (Settings $setting) {
return $setting->translation->value;
},
'format' => 'ntext',
],
[
'class' => ToggleColumn::class,
'attribute' => 'active',
'filter' => [1 => Yii::t('yii', 'Yes'), 0 => Yii::t('yii', 'No')],
'options' => ['style' => 'width: 100px;'],
'contentOptions' => ['class' => 'text-center'],
],
[
'class' => 'yii\grid\ActionColumn',
'options' => ['style' => 'width: 100px;'],
'contentOptions' => ['class' => 'text-center'],
],
],
]
); ?>
<?php Pjax::end(); ?>
</div>
</div>
</div>
</div>
<?php Pjax::begin(); ?>
<?=
GridView::widget(
[
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
//'id',
//'type',
[
'attribute' => 'section',
'filter' => ArrayHelper::map(
Settings::find()->select('section')->distinct()->where(['<>', 'section', ''])->all(),
'section',
'section'
),
],
'key',
'value:ntext',
[
'class' => ToggleColumn::class,
'attribute' => 'active',
'filter' => [1 => Yii::t('yii', 'Yes'), 0 => Yii::t('yii', 'No')],
'options' => ['style' => 'width: 100px;'],
'contentOptions' => ['class' => 'text-center'],
],
[
'class' => 'yii\grid\ActionColumn',
'options' => ['style' => 'width: 100px;'],
'contentOptions' => ['class' => 'text-center'],
],
],
]
); ?>
<?php Pjax::end(); ?>
</div>
</div>
</div> </div>

23
backend/views/settings/list/update.php

@ -9,21 +9,22 @@ use core\entities\Settings;
* @var Settings $settings * @var Settings $settings
*/ */
$this->title = Yii::t( $this->title = Yii::t('main', 'Updating Setting') . ' ' . $model->section . '.' . $model->key;
'main',
'Updating Setting') . ' ' . $model->section. '.' . $model->key;
$this->params['breadcrumbs'][] = ['label' => Yii::t('main', 'Settings'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('main', 'Settings'), 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => $model->section. '.' . $model->key, 'url' => ['view', 'id' => $settings->id]]; $this->params['breadcrumbs'][] = [
'label' => $model->section . '.' . $model->key,
'url' => ['view', 'section' => $settings->section, 'key' => $settings->key]
];
$this->params['breadcrumbs'][] = Yii::t('main', 'Editing'); $this->params['breadcrumbs'][] = Yii::t('main', 'Editing');
?> ?>
<div class="setting-update"> <div class="setting-update">
<?= <?=
$this->render( $this->render(
'_form', '_form',
[ [
'model' => $model, 'model' => $model,
] ]
) ?> ) ?>
</div> </div>

112
backend/views/settings/list/view.php

@ -8,53 +8,77 @@ use yii\widgets\DetailView;
* @var \core\entities\Settings $model * @var \core\entities\Settings $model
*/ */
$this->title = $model->section. '.' . $model->key; $this->title = $model->section . '.' . $model->key;
$this->params['breadcrumbs'][] = ['label' => Yii::t('main', 'Settings'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('main', 'Settings'), 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
$css = <<<CSS
.detail-view th {
width: 25%;
}
CSS;
$this->registerCss($css);
?> ?>
<div class="setting-view"> <div class="setting-view">
<p> <p>
<?= Html::a(Yii::t('buttons','All Settings'), ['index'], ['class' => 'btn btn-default']) ?> <?= Html::a(Yii::t('buttons', 'All Settings'), ['index', 'section' => $model->section], ['class' => 'btn btn-default']) ?>
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?> <?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'section' => $model->section, 'key' => $model->key], ['class' => 'btn btn-primary']) ?>
<?= <?=
Html::a( Html::a(
Yii::t('buttons', 'Delete'), Yii::t('buttons', 'Delete'),
['delete', 'id' => $model->id], ['delete', 'section' => $model->section, 'key' => $model->key],
[ [
'class' => 'btn btn-danger', 'class' => 'btn btn-danger',
'data' => [ 'data' => [
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), 'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'),
'method' => 'post', 'method' => 'post',
], ],
] ]
) ?> ) ?>
</p> </p>
<div class="box"> <div class="box">
<div class="box-body"> <div class="box-body">
<?= <?=
DetailView::widget( DetailView::widget(
[ [
'model' => $model, 'model' => $model,
'attributes' => [ 'attributes' => [
'id', 'type',
'type', 'section',
'section', 'active:boolean',
'active:boolean', 'key',
'key', [
'value:ntext', 'attribute' => 'created_at',
[ 'format' => ['datetime', 'php:d.m.Y H:i'],
'attribute' => 'created_at', ],
'format' => ['datetime', 'php:d.m.Y H:i'], [
], 'attribute' => 'updated_at',
[ 'format' => ['datetime', 'php:d.m.Y H:i'],
'attribute' => 'updated_at', ],
'format' => ['datetime', 'php:d.m.Y H:i'], ],
], ]
], ) ?>
]
) ?> <?php
</div> $items = [];
</div> foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) {
$items[] = [
'label' => $language_name,
'content' => $this->render('_view_tab', [
'setting' => $model,
'language' => $language,
]),
];
}
?>
<div class="nav-tabs-custom">
<?= \yii\bootstrap\Tabs::widget([
'items' => $items,
]) ?>
</div>
</div>
</div>
</div> </div>

110
common/modules/pages/forms/PageForm.php

@ -11,7 +11,7 @@ use Yii;
class PageForm extends LanguageDynamicModel class PageForm extends LanguageDynamicModel
{ {
public $type; public $type;
public $title; public $title;
public $slug; public $slug;
public $content; public $content;
@ -23,71 +23,79 @@ class PageForm extends LanguageDynamicModel
public $_page; public $_page;
public function __construct(Page $page = null, array $attributes = [], $config = []) public function __construct(Page $page = null, array $attributes = [], $config = [])
{ {
if ($page) { if ($page) {
$this->slug = $page->slug; $this->slug = $page->slug;
$this->parentId = $page->parent ? $page->parent->id : null; $this->parentId = $page->parent ? $page->parent->id : null;
$this->_page = $page; $this->_page = $page;
} }
parent::__construct( $page, $attributes, $config ); parent::__construct($page, $attributes, $config);
} }
public function rules(): array public function rules(): array
{ {
return array_merge( return array_merge(
parent::rules(), parent::rules(),
[ [
[['title'], 'required'], [['title'], 'required'],
[['parentId'], 'integer'], [['parentId'], 'integer'],
[['title', 'slug', 'meta_title', 'meta_keywords'], 'string', 'max' => 255], [['title', 'slug', 'meta_title', 'meta_keywords'], 'string', 'max' => 255],
[['content', 'meta_description'], 'string'], [['content', 'meta_description'], 'string'],
['slug', SlugValidator::class], ['slug', SlugValidator::class],
[['slug'], 'unique', 'targetClass' => Page::class, 'filter' => function (ActiveQuery $query) { [
if ($this->type != Page::TYPE_PUBLIC) { ['slug'],
$query->andWhere($this->type . '=' . Page::TYPE_PUBLIC); 'unique',
} 'targetClass' => Page::class,
'filter' => function (ActiveQuery $query) {
if ($this->type != Page::TYPE_PUBLIC) {
$query->andWhere($this->type . '=' . Page::TYPE_PUBLIC);
}
$query->andWhere(['type' => Page::TYPE_PUBLIC]); $query->andWhere(['type' => Page::TYPE_PUBLIC]);
if ($this->_page) { if ($this->_page) {
$query->andWhere(['<>', 'id', $this->_page->id]); $query->andWhere(['<>', 'id', $this->_page->id]);
} }
return $query;
}], return $query;
] }
); ],
]
);
} }
public function attributeLabels() { public function attributeLabels()
return array_merge( {
parent::attributeLabels(), return array_merge(
[ parent::attributeLabels(),
'title' => Yii::t('pages', 'Title'), [
'slug' => Yii::t('pages', 'Slug'), 'title' => Yii::t('pages', 'Title'),
'id' => Yii::t('pages', 'ID'), 'slug' => Yii::t('pages', 'Slug'),
'content' => Yii::t('pages', 'Content'), 'id' => Yii::t('pages', 'ID'),
'parentId' => Yii::t('pages', 'Parent Page'), 'content' => Yii::t('pages', 'Content'),
'meta_title' => Yii::t('pages', 'META Title'), 'parentId' => Yii::t('pages', 'Parent Page'),
'meta_description' => Yii::t('pages', 'META Description'), 'meta_title' => Yii::t('pages', 'META Title'),
'meta_keywords' => Yii::t('pages', 'META Keywords'), 'meta_description' => Yii::t('pages', 'META Description'),
] 'meta_keywords' => Yii::t('pages', 'META Keywords'),
); ]
} );
}
public function attributeHints() { public function attributeHints()
return array_merge( {
parent::attributeHints(), return array_merge(
[ parent::attributeHints(),
'slug' => Yii::t('pages', 'SEO link will be generated automatically if not specified'), [
] 'slug' => Yii::t('pages', 'SEO link will be generated automatically if not specified'),
); ]
} );
}
public function parentsList(): array public function parentsList(): array
{ {
return ArrayHelper::map(Page::find()->andWhere(['tree' => 1])->orderBy('lft')->all(), 'id', function (Page $page) { return ArrayHelper::map(Page::find()->andWhere(['tree' => 1])->orderBy('lft')->all(), 'id', function (Page $page) {
return ($page->depth > 1 ? str_repeat('-- ', $page->depth - 1) . ' ' : '') . ($page->translation ? $page->translation->title : Yii::t('pages', '- no parent -')); return ($page->depth > 1 ? str_repeat('-- ', $page->depth - 1) . ' ' : '') . ($page->translation ? $page->translation->title : Yii::t('pages', '- no parent -'));
}); });
} }
} }

153
common/modules/pages/views/manage/page/_form.php

@ -1,6 +1,5 @@
<?php <?php
use zertex\ckeditor\CKEditor;
use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\ActiveForm; use yii\widgets\ActiveForm;
@ -29,86 +28,78 @@ $this->registerJs($js2);
<?php $form = ActiveForm::begin(); ?> <?php $form = ActiveForm::begin(); ?>
<div class="row"> <div class="row">
<div class="col-md-10"> <div class="col-md-10">
<div class="box box-default"> <div class="box box-default">
<div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div> <div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div>
<div class="box-body"> <div class="box-body">
<?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?> <?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?>
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?>
</div> </div>
</div> </div>
<?php <?php
$items = []; $items = [];
foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) { foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) {
$items[] = [ $items[] = [
'label' => $language_name, 'label' => $language_name,
'content' => $this->render('_form_tab', [ 'content' => $this->render('_form_tab', [
'form' => $form, 'form' => $form,
'model' => $model, 'model' => $model,
'language' => $language, 'language' => $language,
]), ]),
]; ];
} }
?> ?>
<div class="nav-tabs-custom"> <div class="nav-tabs-custom">
<?= \yii\bootstrap\Tabs::widget([ <?= \yii\bootstrap\Tabs::widget([
'items' => $items 'items' => $items
]) ?> ]) ?>
</div> </div>
<!-- <div class="form-group">
<div class="box box-default"> <?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
<div class="box-header with-border"><?= Yii::t('pages', 'SEO') ?></div> </div>
<div class="box-body">
< ?= $form->field($model->meta, 'title')->textInput() ?> </div>
< ?= $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?>
< ?= $form->field($model->meta, 'keywords')->textInput() ?> <div class="col-md-2">
</div> <div class="box box-default">
</div> <div class="box-header with-border"><?= Yii::t('pages', 'Publish') ?></div>
--> <div class="box-body">
<div class="form-group"> <div class="btn-group">
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?> <button type="button" class="btn btn-info"><?= Yii::t('pages', 'Preview on site') ?></button>
</div> <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
</div> <span class="sr-only">Toggle Dropdown</span>
</button>
<div class="col-md-2"> <ul class="dropdown-menu" role="menu">
<div class="box box-default"> <?php foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) : ?>
<div class="box-header with-border"><?= Yii::t('pages', 'Publish') ?></div> <li>
<div class="box-body"> <?= Html::submitButton($language_name, [
'class' => 'btn btn-block btn-flat bg-white',
<div class="btn-group"> 'value' => 'preview',
<button type="button" class="btn btn-info"><?= Yii::t('pages', 'Preview on site') ?></button> 'name' => 'submit_preview',
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"> 'formaction' => \yii\helpers\Url::to([
<span class="caret"></span> '/pages/manage/page/create-preview',
<span class="sr-only">Toggle Dropdown</span> 'language' => $language == Yii::$app->params['defaultLanguage'] ? '' : $language
</button> ]),
<ul class="dropdown-menu" role="menu"> 'formtarget' => '_blank',
<?php foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name): ?> 'style' => 'border:0; background-color:#ffffff;',
<li> ]) ?>
<?= Html::submitButton($language_name, [ </li>
'class' => 'btn btn-block btn-flat bg-white', <?php endforeach; ?>
'value'=>'preview', </ul>
'name'=>'submit_preview', </div>
'formaction' => \yii\helpers\Url::to(['/pages/manage/page/create-preview', 'language' => $language == Yii::$app->params['defaultLanguage'] ? '' : $language]),
'formtarget' => '_blank', </div>
'style' => 'border:0; background-color:#ffffff;', </div>
]) ?> </div>
</li>
<?php endforeach; ?> </div>
</ul>
</div>
</div>
</div>
</div>
</div>
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>

192
common/modules/pages/views/manage/page/view.php

@ -7,7 +7,7 @@ use yii\widgets\DetailView;
/* @var $page \common\modules\pages\entities\Page */ /* @var $page \common\modules\pages\entities\Page */
/* @var $history \common\modules\pages\entities\Page[] */ /* @var $history \common\modules\pages\entities\Page[] */
$this->title = $page->translation->title; $this->title = $page->translation->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('pages', 'Pages'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('pages', 'Pages'), 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
@ -21,104 +21,112 @@ $this->registerCss($css);
<div class="user-view"> <div class="user-view">
<p> <p>
<?= Html::a(Yii::t('pages','Pages'), ['index'], ['class' => 'btn btn-default']) ?> <?= Html::a(Yii::t('pages', 'Pages'), ['index'], ['class' => 'btn btn-default']) ?>
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $page->id], ['class' => 'btn btn-primary']) ?> <?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $page->id], ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $page->id], [ <?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $page->id], [
'class' => 'btn btn-danger', 'class' => 'btn btn-danger',
'data' => [ 'data' => [
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'), 'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'),
'method' => 'post', 'method' => 'post',
], ],
]) ?> ]) ?>
</p> </p>
<div class="row"> <div class="row">
<div class="col-md-9"> <div class="col-md-9">
<div class="box"> <div class="box">
<div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div> <div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div>
<div class="box-body"> <div class="box-body">
<?= DetailView::widget([ <?= DetailView::widget([
'model' => $page, 'model' => $page,
'attributes' => [ 'attributes' => [
'id', 'id',
'slug', 'slug',
], ],
]) ?> ]) ?>
</div> </div>
</div> </div>
<?php <?php
$items = []; $items = [];
foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) { foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) {
$items[] = [ $items[] = [
'label' => $language_name, 'label' => $language_name,
'content' => $this->render('_view_tab', [ 'content' => $this->render('_view_tab', [
'page' => $page, 'page' => $page,
'language' => $language, 'language' => $language,
]), ]),
]; ];
} }
?> ?>
<div class="nav-tabs-custom"> <div class="nav-tabs-custom">
<?= \yii\bootstrap\Tabs::widget([ <?= \yii\bootstrap\Tabs::widget([
'items' => $items, 'items' => $items,
]) ?> ]) ?>
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="box"> <div class="box">
<div class="box-header with-border"><?= Yii::t('pages', 'History') ?></div> <div class="box-header with-border"><?= Yii::t('pages', 'History') ?></div>
<div class="box-body"> <div class="box-body">
<?php if ($history): ?> <?php if ($history): ?>
<ul> <ul>
<?php foreach ($history as $item): ?> <?php foreach ($history as $item): ?>
<li> <li>
<?php if ($item->revision_id): ?> <?php if ($item->revision_id): ?>
<?= date('d.m.Y H:i', $item->revision_at) ?> <?= date('d.m.Y H:i', $item->revision_at) ?>
<?= Html::a(Yii::t('blog', 'View'), \yii\helpers\Url::to(Yii::$app->get('frontendUrlManager')->createAbsoluteUrl(['/pages/page/preview', 'id' => $item->id])), [ <?= Html::a(Yii::t('blog', 'View'),
'style' => 'font-size:11px;', \yii\helpers\Url::to(Yii::$app->get('frontendUrlManager')->createAbsoluteUrl([
'target' => '_blank', '/pages/page/preview',
]) ?> 'id' => $item->id
])), [
| 'style' => 'font-size:11px;',
'target' => '_blank',
<?= Html::a(Yii::t('pages', 'Restore'), ['/pages/manage/page/restore-history', 'id' => $item->id], [ ]) ?>
'style' => 'font-size:11px; color: red',
'data' => [ |
'confirm' => Yii::t('pages', 'Are you sure you want to restore this history item?'),
'method' => 'post', <?= Html::a(Yii::t('pages', 'Restore'),
], ['/pages/manage/page/restore-history', 'id' => $item->id], [
]) ?> 'style' => 'font-size:11px; color: red',
'data' => [
<?php else: ?> 'confirm' => Yii::t('pages',
<strong><?= Yii::t('pages', 'Current Edition') ?></strong> 'Are you sure you want to restore this history item?'),
<?php endif; ?> 'method' => 'post',
</li> ],
<?php endforeach; ?> ]) ?>
</ul>
<?php else: ?>
<?= Html::a(Yii::t('pages', 'Clear History'), ['/pages/manage/page/clear-history', 'id' => $page->id], [ <strong><?= Yii::t('pages', 'Current Edition') ?></strong>
'class' => 'btn btn-danger btn-sm pull-right', <?php endif; ?>
'data' => [ </li>
'confirm' => Yii::t('pages', 'Are you sure you want to remove this history?'), <?php endforeach; ?>
'method' => 'post', </ul>
],
]) ?> <?= Html::a(Yii::t('pages', 'Clear History'),
<?php else: ?> ['/pages/manage/page/clear-history', 'id' => $page->id], [
<div style="padding: 20px 0; text-align: center"><?= Yii::t('pages', 'History is empty') ?></div> 'class' => 'btn btn-danger btn-sm pull-right',
<?php endif; ?> 'data' => [
'confirm' => Yii::t('pages', 'Are you sure you want to remove this history?'),
</div> 'method' => 'post',
</div> ],
</div> ]) ?>
<?php else: ?>
</div> <div style="padding: 20px 0; text-align: center"><?= Yii::t('pages',
'History is empty') ?></div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div> </div>

42
console/migrations/m180604_124108_create_settings_table.php

@ -12,25 +12,25 @@ class m180604_124108_create_settings_table extends Migration
*/ */
public function up() public function up()
{ {
$tableOptions = null; $tableOptions = null;
if ($this->db->driverName === 'mysql') { if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
} }
$this->createTable( $this->createTable(
'{{%settings}}', '{{%settings}}',
[ [
'id' => $this->primaryKey(), 'id' => $this->primaryKey(),
'type' => $this->string(255)->notNull(), 'type' => $this->string(255)->notNull(),
'section' => $this->string(255)->notNull(), 'section' => $this->string(255)->notNull(),
'key' => $this->string(255)->notNull(), 'key' => $this->string(255)->notNull(),
'value' => $this->text(), 'value' => $this->text(),
'active' => $this->integer(1), 'active' => $this->integer(1),
'created_at' => $this->integer()->unsigned(), 'created_at' => $this->integer()->unsigned(),
'updated_at' => $this->integer()->unsigned(), 'updated_at' => $this->integer()->unsigned(),
], ],
$tableOptions $tableOptions
); );
$this->createIndex('settings_unique_key_section', '{{%settings}}', ['section', 'key'], true); $this->createIndex('settings_unique_key_section', '{{%settings}}', ['section', 'key'], true);
} }
/** /**
@ -38,7 +38,7 @@ class m180604_124108_create_settings_table extends Migration
*/ */
public function down() public function down()
{ {
$this->dropIndex('settings_unique_key_section', '{{%settings}}'); $this->dropIndex('settings_unique_key_section', '{{%settings}}');
$this->dropTable('{{%settings}}'); $this->dropTable('{{%settings}}');
} }
} }

28
console/migrations/m180824_081717_create_menu_lng_table.php

@ -12,21 +12,21 @@ class m180824_081717_create_menu_lng_table extends Migration
*/ */
public function safeUp() public function safeUp()
{ {
$tableOptions = null; $tableOptions = null;
if ($this->db->driverName === 'mysql') { if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
} }
$this->createTable('{{%menu_lng}}', [ $this->createTable('{{%menu_lng}}', [
'id' => $this->primaryKey(), 'id' => $this->primaryKey(),
'menu_id' => $this->integer()->notNull(), 'menu_id' => $this->integer()->notNull(),
'language' => $this->string(6)->notNull(), 'language' => $this->string(6)->notNull(),
'name' => $this->string(255)->notNull(), 'name' => $this->string(255)->notNull(),
], $tableOptions); ], $tableOptions);
$this->createIndex('idx_menu_lng_language', '{{%menu_lng}}', 'language'); $this->createIndex('idx_menu_lng_language', '{{%menu_lng}}', 'language');
$this->createIndex('idx_menu_lng_menu_id', '{{%menu_lng}}', 'menu_id'); $this->createIndex('idx_menu_lng_menu_id', '{{%menu_lng}}', 'menu_id');
$this->addForeignKey('frg_menu_lng_menu_menu_id_id', '{{%menu_lng}}', 'menu_id', '{{%menu}}', 'id', 'CASCADE', 'CASCADE'); $this->addForeignKey('frg_menu_lng_menu_menu_id_id', '{{%menu_lng}}', 'menu_id', '{{%menu}}', 'id', 'CASCADE', 'CASCADE');
} }
/** /**
@ -34,9 +34,9 @@ class m180824_081717_create_menu_lng_table extends Migration
*/ */
public function safeDown() public function safeDown()
{ {
$this->dropForeignKey('frg_menu_lng_menu_menu_id_id', '{{%menu_lng}}'); $this->dropForeignKey('frg_menu_lng_menu_menu_id_id', '{{%menu_lng}}');
$this->dropColumn('idx_menu_lng_menu_id', '{{%menu_lng}}'); $this->dropColumn('idx_menu_lng_menu_id', '{{%menu_lng}}');
$this->dropColumn('idx_menu_lng_language', '{{%menu_lng}}'); $this->dropColumn('idx_menu_lng_language', '{{%menu_lng}}');
$this->dropTable('{{%menu_lng}}'); $this->dropTable('{{%menu_lng}}');
} }
} }

14
console/migrations/m180827_194913_set_core_tables_unicode_oollate.php

@ -12,15 +12,15 @@ class m180827_194913_set_core_tables_unicode_oollate extends Migration
*/ */
public function safeUp() public function safeUp()
{ {
$tables = ['user_networks', 'settings', 'modules', 'menu', 'menu_items', 'menu_lng', 'menu_items_lng']; $tables = ['user_networks', 'settings', 'modules', 'menu', 'menu_items', 'menu_lng', 'menu_items_lng'];
$db = Yii::$app->getDb(); $db = Yii::$app->getDb();
$db->createCommand('SET FOREIGN_KEY_CHECKS=0;')->execute(); $db->createCommand('SET FOREIGN_KEY_CHECKS=0;')->execute();
foreach ($tables as $table) { foreach ($tables as $table) {
$db->createCommand( "ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci" )->execute(); $db->createCommand("ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci")->execute();
} }
$db->createCommand('SET FOREIGN_KEY_CHECKS=1;')->execute(); $db->createCommand('SET FOREIGN_KEY_CHECKS=1;')->execute();
} }
/** /**

50
console/migrations/m180910_182109_create_settings_lng_table.php

@ -0,0 +1,50 @@
<?php
use yii\db\Migration;
/**
* Handles the creation of table `settings_lng`.
*/
class m180910_182109_create_settings_lng_table extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}
$this->createTable('{{%settings_lng}}', [
'id' => $this->primaryKey(),
'language' => $this->string(6)->notNull(),
'section' => $this->string(255)->notNull(),
'key' => $this->string(255)->notNull(),
'value' => $this->text(),
], $tableOptions);
$this->createIndex('key', '{{%settings_lng}}', ['section', 'key']);
$this->createIndex('idx_settings_lng_language', '{{%settings_lng}}', 'language');
$this->addForeignKey('frg_settings_lng_settings_setting_id_id', '{{%settings_lng}}', ['section', 'key'], '{{%settings}}', ['section', 'key'], 'CASCADE', 'CASCADE');
$this->dropColumn('{{%settings}}', 'id');
$this->addPrimaryKey('key', '{{%settings}}', ['section', 'key']);
$this->dropColumn('{{%settings}}', 'value');
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->addColumn('{{%settings}}', 'value', $this->text());
$this->dropPrimaryKey('key', '{{%settings}}');
$this->addColumn('{{%settings}}', 'id', $this->primaryKey());
$this->dropForeignKey('frg_settings_lng_settings_setting_id_id', '{{%settings_lng}}');
$this->dropIndex('idx_settings_lng_language', '{{%settings_lng}}');
$this->dropTable('{{%settings_lng}}');
}
}

78
core/behaviors/LanguageBehavior.php

@ -33,7 +33,7 @@ class LanguageBehavior extends Behavior
/** /**
* Field name for tables relative, ex.: 'post_id' * Field name for tables relative, ex.: 'post_id'
* @var string * @var array|string
*/ */
public $relativeField; public $relativeField;
@ -91,7 +91,8 @@ class LanguageBehavior extends Behavior
/** @var ActiveRecord $owner */ /** @var ActiveRecord $owner */
parent::attach($owner); parent::attach($owner);
if (empty($this->translatedLanguages) || !is_array($this->translatedLanguages)) { if (empty($this->translatedLanguages) || !is_array($this->translatedLanguages)) {
throw new InvalidConfigException('Please specify array of available languages for the ' . get_class($this) . ' in the ' . get_class($this->owner) . ' or in the application parameters', 101); throw new InvalidConfigException('Please specify array of available languages for the ' . get_class($this) . ' in the ' . get_class($this->owner) . ' or in the application parameters',
101);
} }
if (array_values($this->translatedLanguages) !== $this->translatedLanguages) { //associative array if (array_values($this->translatedLanguages) !== $this->translatedLanguages) { //associative array
@ -265,7 +266,14 @@ class LanguageBehavior extends Behavior
/** @var ActiveRecord $translation */ /** @var ActiveRecord $translation */
$translation = new $this->virtualClassName; $translation = new $this->virtualClassName;
$translation->{$this->languageField} = $language; $translation->{$this->languageField} = $language;
$translation->{$this->relativeField} = $owner->getPrimaryKey();
if (is_array($this->relativeField)) {
foreach ($this->relativeField as $field) {
$translation->{$field} = $owner->{$field};
}
} else {
$translation->{$this->relativeField} = $owner->getPrimaryKey();
}
} else { } else {
$translation = $translations[$language]; $translation = $translations[$language];
} }
@ -315,7 +323,16 @@ class LanguageBehavior extends Behavior
public function getTranslations() public function getTranslations()
{ {
/** @var ActiveRecord */ /** @var ActiveRecord */
return $this->owner->hasMany($this->virtualClassName, [$this->relativeField => $this->_ownerPrimaryKey]); $condition = [];
if (is_array($this->relativeField)) {
foreach ($this->relativeField as $field) {
//$condition[$field] = $this->owner->{$field};
$condition[$field] = $field;
}
return $this->owner->hasMany($this->virtualClassName, $condition);
} else {
return $this->owner->hasMany($this->virtualClassName, [$this->relativeField => $this->_ownerPrimaryKey]);
}
} }
public function getTranslation($language = null) public function getTranslation($language = null)
@ -327,15 +344,34 @@ class LanguageBehavior extends Behavior
$language = $language ?: \Yii::$app->language; $language = $language ?: \Yii::$app->language;
//} //}
// if translate exists // if translate exists
$translate = $this->virtualClassName::find() if (is_array($this->relativeField)) {
->andWhere([$this->relativeField => $this->owner->id]) $condition = [];
->andWhere([$this->languageField => $language]) foreach ($this->relativeField as $field) {
->one(); $condition[$field] = $this->owner->{$field};
}
$translate = $this->virtualClassName::find()
->andWhere($condition)
->andWhere([$this->languageField => $language])
->one();
} else {
$translate = $this->virtualClassName::find()
->andWhere([$this->relativeField => $this->owner->id])
->andWhere([$this->languageField => $language])
->one();
}
$language = $translate ? $language : $this->defaultLanguage; $language = $translate ? $language : $this->defaultLanguage;
return $this->owner->hasOne($this->virtualClassName, [$this->relativeField => $this->_ownerPrimaryKey]) if (is_array($this->relativeField)) {
->where([$this->languageField => $language]); $condition = [];
foreach ($this->relativeField as $field) {
$condition[$field] = $field;
}
return $this->owner->hasOne($this->virtualClassName, $condition)
->where([$this->languageField => $language]);
} else {
return $this->owner->hasOne($this->virtualClassName, [$this->relativeField => $this->_ownerPrimaryKey])
->where([$this->languageField => $language]);
}
} }
public function findTranslation($language = null) public function findTranslation($language = null)
@ -343,10 +379,22 @@ class LanguageBehavior extends Behavior
$language = $language ?: $this->defaultLanguage; $language = $language ?: $this->defaultLanguage;
//$class = call_user_func(array($this->virtualClassName, 'getInstance')); //$class = call_user_func(array($this->virtualClassName, 'getInstance'));
return $this->virtualClassName::find()
->andWhere([$this->relativeField => $this->owner->id]) if (is_array($this->relativeField)) {
->andWhere([$this->languageField => $language]) $condition = [];
->one(); foreach ($this->relativeField as $field) {
$condition[$field] = $this->owner{$field};
}
return $this->virtualClassName::find()
->andWhere($condition)
->andWhere([$this->languageField => $language])
->one();
} else {
return $this->virtualClassName::find()
->andWhere([$this->relativeField => $this->owner->id])
->andWhere([$this->languageField => $language])
->one();
}
} }
public function hasLangAttribute($name) public function hasLangAttribute($name)

24
core/entities/Settings.php

@ -9,9 +9,9 @@ namespace core\entities;
use Yii; use Yii;
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior; use yii\behaviors\TimestampBehavior;
use core\behaviors\LanguageBehavior;
/** /**
* @property integer $id
* @property string $type * @property string $type
* @property string $section * @property string $section
* @property string $key * @property string $key
@ -23,6 +23,8 @@ use yii\behaviors\TimestampBehavior;
class Settings extends ActiveRecord class Settings extends ActiveRecord
{ {
public $_form;
public static function tableName(): string public static function tableName(): string
{ {
return '{{%settings}}'; return '{{%settings}}';
@ -31,7 +33,6 @@ class Settings extends ActiveRecord
public function attributeLabels() public function attributeLabels()
{ {
return [ return [
'id' => Yii::t('main', 'ID'),
'type' => Yii::t('main', 'Type'), 'type' => Yii::t('main', 'Type'),
'section' => Yii::t('main', 'Section'), 'section' => Yii::t('main', 'Section'),
'key' => Yii::t('main', 'Key'), 'key' => Yii::t('main', 'Key'),
@ -42,31 +43,42 @@ class Settings extends ActiveRecord
]; ];
} }
public static function create($type, $section, $key, $value, $active): self public static function create($form, $type, $section, $key, $active): self
{ {
$settings = new static(); $settings = new static();
$settings->type = $type; $settings->type = $type;
$settings->section = $section; $settings->section = $section;
$settings->key = $key; $settings->key = $key;
$settings->value = $value;
$settings->active = $active; $settings->active = $active;
$settings->_form = $form;
return $settings; return $settings;
} }
public function edit($type, $section, $key, $value, $active): void public function edit($form, $type, $section, $key, $active): void
{ {
$this->type = $type; $this->type = $type;
$this->section = $section; $this->section = $section;
$this->key = $key; $this->key = $key;
$this->value = $value;
$this->active = $active; $this->active = $active;
$this->_form = $form;
} }
public function behaviors(): array public function behaviors(): array
{ {
return [ return [
TimestampBehavior::class, TimestampBehavior::class,
[
'class' => LanguageBehavior::class,
'virtualClassName' => 'SettingsVirtualTranslate',
'translatedLanguages' => \Yii::$app->params['translatedLanguages'],
'relativeField' => ['section', 'key'],
'tableName' => '{{%settings_lng}}',
'attributes' => ['value'],
'defaultLanguage' => \Yii::$app->params['defaultLanguage'],
],
]; ];
} }
} }

229
core/forms/SettingsForm.php

@ -6,122 +6,135 @@
namespace core\forms; namespace core\forms;
use core\components\LanguageDynamicModel;
use core\entities\Settings; use core\entities\Settings;
use yii\base\DynamicModel; use yii\base\DynamicModel;
use yii\base\Model;
use yii\helpers\Json; use yii\helpers\Json;
use yii\base\InvalidParamException;
use Yii; use Yii;
class SettingsForm extends Model class SettingsForm extends LanguageDynamicModel
{ {
public $type; public $type;
public $section; public $section;
public $key; public $key;
public $value; public $value;
public $active; public $active;
private $_settings;
public $_settings;
//public function __construct(Settings $settings = null, $config = [])
public function __construct(Settings $settings = null, array $attributes = [], $config = [])
{
if ($settings) {
$this->type = $settings->type;
$this->section = $settings->section;
$this->key = $settings->key;
$this->value = $settings->value;
$this->active = $settings->active;
$this->_settings = $settings;
}
//parent::__construct($config);
parent::__construct($settings, $attributes, $config);
}
public function rules()
{
return array_merge(
parent::rules(),
[
[['value'], 'string'],
[['section', 'key'], 'string', 'max' => 255],
[
['key'],
'unique',
'targetAttribute' => ['section', 'key'],
'targetClass' => Settings::class,
//'filter' => $this->_settings ? ['<>', 'id', $this->_settings->id] : null,
'filter' => $this->_settings ? ['AND', ['<>', 'section', $this->_settings->section], ['<>', 'key', $this->_settings->key]] : null,
'message' =>
Yii::t('main', '{attribute} "{value}" already exists for this section.')
],
['type', 'in', 'range' => array_keys($this->getTypes(false))],
[['type'], 'safe'],
[['active'], 'integer'],
]
);
}
public function getTypes($forDropDown = true)
{
$values = [
'string' => ['value', 'string'],
'integer' => ['value', 'integer'],
'boolean' => ['value', 'boolean', 'trueValue' => '1', 'falseValue' => '0', 'strict' => true],
'float' => ['value', 'number'],
'email' => ['value', 'email'],
'ip' => ['value', 'ip'],
'url' => ['value', 'url'],
'object' => [
'value',
function ($attribute) {
$object = null;
try {
Json::decode($this->$attribute);
} catch (\InvalidArgumentException $e) {
$this->addError($attribute, Yii::t('main', '"{attribute}" must be a valid JSON object', [
'attribute' => $attribute,
]));
}
}
],
];
if (!$forDropDown) {
return $values;
}
$return = [];
foreach ($values as $key => $value) {
$return[$key] = Yii::t('main', $key);
}
return $return;
}
public function __construct(Settings $settings = null, $config = []) public function attributeLabels()
{ {
if ($settings) { return array_merge(
$this->type = $settings->type; parent::attributeLabels(),
$this->section = $settings->section; [
$this->key = $settings->key; 'id' => Yii::t('main', 'ID'),
$this->value = $settings->value; 'type' => Yii::t('main', 'Type'),
$this->active = $settings->active; 'section' => Yii::t('main', 'Section'),
$this->_settings = $settings; 'key' => Yii::t('main', 'Key'),
} 'value' => Yii::t('main', 'Value'),
parent::__construct($config); 'active' => Yii::t('main', 'Active'),
} 'crated_at' => Yii::t('main', 'Created At'),
'updated_at' => Yii::t('main', 'Updated At'),
]
);
}
public function rules() public function beforeValidate()
{ {
return [ $validators = $this->getTypes(false);
[['value'], 'string'], if (!array_key_exists($this->type, $validators)) {
[['section', 'key'], 'string', 'max' => 255], $this->addError('type', Yii::t('main', 'Please select correct type'));
[
['key'],
'unique',
'targetAttribute' => ['section', 'key'],
'targetClass' => Settings::class,
'filter' => $this->_settings ? ['<>', 'id', $this->_settings->id] : null,
'message' =>
Yii::t('main', '{attribute} "{value}" already exists for this section.')
],
['type', 'in', 'range' => array_keys($this->getTypes(false))],
[['type'], 'safe'],
[['active'], 'integer'],
];
}
public function getTypes($forDropDown = true) return false;
{ }
$values = [ $model = DynamicModel::validateData([
'string' => ['value', 'string'], 'value' => $this->value
'integer' => ['value', 'integer'], ], [
'boolean' => ['value', 'boolean', 'trueValue' => "1", 'falseValue' => "0", 'strict' => true], $validators[$this->type],
'float' => ['value', 'number'], ]);
'email' => ['value', 'email'], if ($model->hasErrors()) {
'ip' => ['value', 'ip'], $this->addError('value', $model->getFirstError('value'));
'url' => ['value', 'url'],
'object' => [
'value',
function ($attribute) {
$object = null;
try {
Json::decode($this->$attribute);
} catch (InvalidParamException $e) {
$this->addError($attribute, Yii::t('main', '"{attribute}" must be a valid JSON object', [
'attribute' => $attribute,
]));
}
}
],
];
if (!$forDropDown) {
return $values;
}
$return = [];
foreach ($values as $key => $value) {
$return[$key] = Yii::t('main', $key);
}
return $return;
}
public function attributeLabels() return false;
{ }
return [ if ($this->hasErrors()) {
'id' => Yii::t('main', 'ID'), return false;
'type' => Yii::t('main', 'Type'), }
'section' => Yii::t('main', 'Section'),
'key' => Yii::t('main', 'Key'),
'value' => Yii::t('main', 'Value'),
'active' => Yii::t('main', 'Active'),
'crated_at' => Yii::t('main', 'Created At'),
'updated_at' => Yii::t('main', 'Updated At'),
];
}
public function beforeValidate() { return parent::beforeValidate();
$validators = $this->getTypes(false); }
if (!array_key_exists($this->type, $validators)) { }
$this->addError('type', Yii::t('main', 'Please select correct type'));
return false;
}
$model = DynamicModel::validateData([
'value' => $this->value
], [
$validators[$this->type],
]);
if ($model->hasErrors()) {
$this->addError('value', $model->getFirstError('value'));
return false;
}
if ($this->hasErrors()) {
return false;
}
return parent::beforeValidate();
}
}

6
core/repositories/SettingsRepository.php

@ -6,9 +6,9 @@ use core\entities\Settings;
class SettingsRepository class SettingsRepository
{ {
public function get($id): Settings public function get($section, $key): Settings
{ {
if (!$settings = Settings::findOne($id)) { if (!$settings = Settings::find()->andWhere(['section' => $section])->andWhere(['key' => $key])->one()) {
throw new NotFoundException('Setting is not found.'); throw new NotFoundException('Setting is not found.');
} }
return $settings; return $settings;
@ -27,4 +27,4 @@ class SettingsRepository
throw new \RuntimeException('Removing error.'); throw new \RuntimeException('Removing error.');
} }
} }
} }

12
core/services/SettingsService.php

@ -18,10 +18,10 @@ class SettingsService
public function create(SettingsForm $form): Settings public function create(SettingsForm $form): Settings
{ {
$settings = Settings::create( $settings = Settings::create(
$form,
$form->type, $form->type,
$form->section, $form->section,
$form->key, $form->key,
$form->value,
$form->active $form->active
); );
$this->_repository->save($settings); $this->_repository->save($settings);
@ -29,22 +29,22 @@ class SettingsService
return $settings; return $settings;
} }
public function edit($id, SettingsForm $form): void public function edit($section, $key, SettingsForm $form): void
{ {
$settings = $this->_repository->get($id); $settings = $this->_repository->get($section, $key);
$settings->edit( $settings->edit(
$form,
$form->type, $form->type,
$form->section, $form->section,
$form->key, $form->key,
$form->value,
$form->active $form->active
); );
$this->_repository->save($settings); $this->_repository->save($settings);
} }
public function remove($id): void public function remove($section, $key): void
{ {
$settings = $this->_repository->get($id); $settings = $this->_repository->get($section, $key);
$this->_repository->remove($settings); $this->_repository->remove($settings);
} }
} }

Loading…
Cancel
Save