Browse Source

Settings languages

master
Egorka 6 years ago
parent
commit
3a3e813cbe
  1. 80
      backend/bootstrap/SetUp.php
  2. 28
      backend/controllers/settings/ListController.php
  3. 105
      backend/forms/SettingsSearch.php
  4. 80
      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. 227
      core/forms/SettingsForm.php
  22. 4
      core/repositories/SettingsRepository.php
  23. 12
      core/services/SettingsService.php

80
backend/bootstrap/SetUp.php

@ -16,45 +16,59 @@ class SetUp implements BootstrapInterface
$container = \Yii::$container;
// init presets
$presetsPath = \Yii::getAlias('@core/components/ckeditor/presets');
// basic
$app->params['ckeditor']['basic']['toolbar'] = require $presetsPath . '/basic/toolbar.php';
$app->params['ckeditor']['basic']['plugins'] = require $presetsPath . '/basic/plugins.php';
// editor
$app->params['ckeditor']['editor']['toolbar'] = require $presetsPath . '/editor/toolbar.php';
$app->params['ckeditor']['editor']['plugins'] = require $presetsPath . '/editor/plugins.php';
// debeloper
$app->params['ckeditor']['developer']['toolbar'] = require $presetsPath . '/developer/toolbar.php';
$app->params['ckeditor']['developer']['plugins'] = require $presetsPath . '/developer/plugins.php';
// set preset example
/*$form->field($model, 'content')->widget(CKEditor::class, [
'editorOptions' => \zertex\elfinder\ElFinder::ckeditorOptions('elfinder',[
'toolbar' => Yii::$app->params['ckeditor']['editor']['toolbar'],
'extraPlugins' => Yii::$app->params['ckeditor']['editor']['plugins'],
])
])*/
$presetsPath = \Yii::getAlias('@core/components/ckeditor/presets');
// basic
$app->params['ckeditor']['basic']['toolbar'] = require $presetsPath . '/basic/toolbar.php';
$app->params['ckeditor']['basic']['plugins'] = require $presetsPath . '/basic/plugins.php';
// editor
$app->params['ckeditor']['editor']['toolbar'] = require $presetsPath . '/editor/toolbar.php';
$app->params['ckeditor']['editor']['plugins'] = require $presetsPath . '/editor/plugins.php';
// debeloper
$app->params['ckeditor']['developer']['toolbar'] = require $presetsPath . '/developer/toolbar.php';
$app->params['ckeditor']['developer']['plugins'] = require $presetsPath . '/developer/plugins.php';
// set preset example
/*$form->field($model, 'content')->widget(CKEditor::class, [
'editorOptions' => \zertex\elfinder\ElFinder::ckeditorOptions('elfinder',[
'toolbar' => Yii::$app->params['ckeditor']['editor']['toolbar'],
'extraPlugins' => Yii::$app->params['ckeditor']['editor']['plugins'],
])
])*/
$container->set(CKEditor::class, [
'editorOptions' => ElFinder::ckeditorOptions('elfinder', [
'toolbar' => $app->params['ckeditor']['editor']['toolbar'],
'extraPlugins' => $app->params['ckeditor']['editor']['plugins'],
'language' => $app->language,
'toolbar' => $app->params['ckeditor']['editor']['toolbar'],
'extraPlugins' => $app->params['ckeditor']['editor']['plugins'],
'language' => $app->language,
]),
]);
// load settings
$settings = ArrayHelper::map(Settings::find()->andWhere(['active' => 1])->all(), 'key', 'value', 'section');
$app->params['settings'] = $settings;
// 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>',
]);
$settings = Settings::find()->with('translations')->andWhere(['active' => 1])->all();
//$settings = Settings::find()->andWhere(['active' => 1])->all();
//$settings_array = [];
/*foreach ($settings as $setting) {
if (!isset($settings_array[$setting->section])) {
$settings_array[$setting->section] = [];
}
//$settings_array[$setting->section][$setting->key] = $setting->translation->value;
}*/
$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->section = $section;
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render(
@ -74,16 +75,17 @@ class ListController extends Controller
[
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'section' => $section,
]
);
}
public function actionView($id)
public function actionView($section, $key)
{
return $this->render(
'view',
[
'model' => $this->findModel($id),
'model' => $this->findModel($section, $key),
]
);
}
@ -95,7 +97,7 @@ class ListController extends Controller
try {
$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) {
Yii::$app->errorHandler->logException($e);
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);
if ($form->load(Yii::$app->request->post()) && $form->validate()) {
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) {
Yii::$app->errorHandler->logException($e);
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']);
}
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;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
throw new NotFoundHttpException('The requested setting does not exist.');
}
}
}

105
backend/forms/SettingsSearch.php

@ -6,61 +6,68 @@
namespace backend\forms;
use core\entities\Settings;
use yii\base\Model;
use yii\data\ActiveDataProvider;
class SettingsSearch extends Settings
{
public $id;
public $type;
public $section;
public $key;
public $value;
public $active;
public $id;
public $type;
public $section;
public $key;
public $value;
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()
{
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();
}
/**
* @param $params
* @return ActiveDataProvider
*/
public function search($params)
{
$query = Settings::find();
$dataProvider = new ActiveDataProvider(
[
'query' => $query,
]
);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere(
[
'id' => $this->id,
'active' => $this->active,
'section' => $this->section,
]
);
$query->andFilterWhere(['like', 'key', $this->key])
->andFilterWhere(['like', 'value', $this->value]);
return $dataProvider;
}
/**
* @param $params
*
* @return ActiveDataProvider
*/
public function search($params)
{
$query = Settings::find();
$dataProvider = new ActiveDataProvider(
[
'query' => $query,
]
);
if (!($this->load($params) && $this->validate())) {
$query->andFilterWhere(
[
'section' => $this->section,
]
);
return $dataProvider;
}
$query->andFilterWhere(
[
'id' => $this->id,
'active' => $this->active,
'section' => $this->section,
]
);
$query->andFilterWhere(['like', 'key', $this->key])
->andFilterWhere(['like', 'value', $this->value]);
return $dataProvider;
}
}

80
backend/messages/ru/main.php

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

81
backend/views/layouts/header.php

@ -1,6 +1,6 @@
<?php
use yii\helpers\Html;
use core\components\avatar_generator\AvatarGenerator;
/* @var $this \yii\web\View */
/* @var $content string */
@ -10,7 +10,7 @@ use core\components\avatar_generator\AvatarGenerator;
<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">
@ -23,7 +23,7 @@ use core\components\avatar_generator\AvatarGenerator;
<ul class="nav navbar-nav">
<!-- Messages: style can be found in dropdown.less-->
<!--
<!--
<li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<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>
</ul>
</li>
-->
-->
<?= \backend\widgets\NotificationCountWidget::widget() ?>
<?= \backend\widgets\NotificationCountWidget::widget() ?>
<!-- Tasks: style can be found in dropdown.less -->
<!--
<!--
<li class="dropdown tasks-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-flag-o"></i>
@ -191,55 +191,60 @@ use core\components\avatar_generator\AvatarGenerator;
</li>
</ul>
</li>
-->
-->
<!-- Language Drop Down -->
<li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<!-- <i class="fa fa-language"></i> -->
<span><?= \core\helpers\LanguageHelper::getBackendName(Yii::$app->user->identity->user->backend_language) ?> <i class="caret"></i></span>
</a>
<ul class="dropdown-menu">
<li class="header"><?= Yii::t('main', 'Interface Language') ?></li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
<?php foreach (Yii::$app->params['backendTranslatedLanguages'] as $language => $language_name): ?>
<li>
<?= Html::a($language_name, ['/site/language', 'language' => $language], [
'data-method' => 'post'
]) ?>
</li>
<?php endforeach; ?>
</ul>
</li>
</ul>
</li>
<!-- Language Drop Down -->
<li class="dropdown messages-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<!-- <i class="fa fa-language"></i> -->
<span><?= \core\helpers\LanguageHelper::getBackendName(Yii::$app->user->identity->user->backend_language) ?>
<i class="caret"></i></span>
</a>
<ul class="dropdown-menu">
<li class="header"><?= Yii::t('main', 'Interface Language') ?></li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
<?php foreach (Yii::$app->params['backendTranslatedLanguages'] as $language => $language_name): ?>
<li>
<?= Html::a($language_name, ['/site/language', 'language' => $language], [
'data-method' => 'post'
]) ?>
</li>
<?php endforeach; ?>
</ul>
</li>
</ul>
</li>
<li class="dropdown user user-menu">
<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>
</a>
<ul class="dropdown-menu">
<!-- User image -->
<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 ?>"/>
<p>
<?= 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>
<?= 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>
</p>
</li>
<!-- Menu Footer-->
<li class="user-footer">
<div class="pull-left">
<?= Html::a(
Yii::t('user', 'Profile'),
['/user/profile'],
['class' => 'btn btn-default btn-flat']
) ?>
<?= Html::a(
Yii::t('user', 'Profile'),
['/user/profile'],
['class' => 'btn btn-default btn-flat']
) ?>
</div>
<div class="pull-right">
<?= Html::a(

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

@ -9,35 +9,69 @@ use core\forms\SettingsForm;
* @var SettingsForm $model
* @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="box box-default">
<div class="box-body">
<div class="box box-default">
<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,
]),
];
}
?>
<?=
$form->field($model, 'type')->dropDownList(
$model->getTypes()
)->hint(Yii::t('main', 'Change at your own risk')) ?>
<div class="nav-tabs-custom">
<?= \yii\bootstrap\Tabs::widget([
'items' => $items
]) ?>
</div>
<div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
<div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>
<?php ActiveForm::end(); ?>
</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 \backend\forms\SettingsSearch $searchModel
* @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;
?>
<div class="setting-index">
<p>
<?=
Html::a(
Yii::t('buttons','Create Setting'),
['create'],
['class' => 'btn btn-success']
) ?>
</p>
<p>
<?=
Html::a(
Yii::t('buttons', 'Create Setting'),
['create'],
['class' => 'btn btn-success']
) ?>
</p>
<div class="box">
<div class="box-body">
<div class="row">
<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>

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

@ -9,21 +9,22 @@ use core\entities\Settings;
* @var Settings $settings
*/
$this->title = Yii::t(
'main',
'Updating Setting') . ' ' . $model->section. '.' . $model->key;
$this->title = Yii::t('main', 'Updating Setting') . ' ' . $model->section . '.' . $model->key;
$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');
?>
<div class="setting-update">
<?=
$this->render(
'_form',
[
'model' => $model,
]
) ?>
<?=
$this->render(
'_form',
[
'model' => $model,
]
) ?>
</div>

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

@ -8,53 +8,77 @@ use yii\widgets\DetailView;
* @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'][] = $this->title;
$css = <<<CSS
.detail-view th {
width: 25%;
}
CSS;
$this->registerCss($css);
?>
<div class="setting-view">
<p>
<?= Html::a(Yii::t('buttons','All Settings'), ['index'], ['class' => 'btn btn-default']) ?>
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
<?=
Html::a(
Yii::t('buttons', 'Delete'),
['delete', 'id' => $model->id],
[
'class' => 'btn btn-danger',
'data' => [
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'),
'method' => 'post',
],
]
) ?>
</p>
<div class="box">
<div class="box-body">
<?=
DetailView::widget(
[
'model' => $model,
'attributes' => [
'id',
'type',
'section',
'active:boolean',
'key',
'value:ntext',
[
'attribute' => 'created_at',
'format' => ['datetime', 'php:d.m.Y H:i'],
],
[
'attribute' => 'updated_at',
'format' => ['datetime', 'php:d.m.Y H:i'],
],
],
]
) ?>
</div>
</div>
<p>
<?= Html::a(Yii::t('buttons', 'All Settings'), ['index', 'section' => $model->section], ['class' => 'btn btn-default']) ?>
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'section' => $model->section, 'key' => $model->key], ['class' => 'btn btn-primary']) ?>
<?=
Html::a(
Yii::t('buttons', 'Delete'),
['delete', 'section' => $model->section, 'key' => $model->key],
[
'class' => 'btn btn-danger',
'data' => [
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'),
'method' => 'post',
],
]
) ?>
</p>
<div class="box">
<div class="box-body">
<?=
DetailView::widget(
[
'model' => $model,
'attributes' => [
'type',
'section',
'active:boolean',
'key',
[
'attribute' => 'created_at',
'format' => ['datetime', 'php:d.m.Y H:i'],
],
[
'attribute' => 'updated_at',
'format' => ['datetime', 'php:d.m.Y H:i'],
],
],
]
) ?>
<?php
$items = [];
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>

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

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

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

@ -1,6 +1,5 @@
<?php
use zertex\ckeditor\CKEditor;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
@ -29,86 +28,78 @@ $this->registerJs($js2);
<?php $form = ActiveForm::begin(); ?>
<div class="row">
<div class="col-md-10">
<div class="box box-default">
<div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div>
<div class="box-body">
<?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?>
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?>
</div>
</div>
<?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">
<?= \yii\bootstrap\Tabs::widget([
'items' => $items
]) ?>
</div>
<!--
<div class="box box-default">
<div class="box-header with-border"><?= Yii::t('pages', 'SEO') ?></div>
<div class="box-body">
< ?= $form->field($model->meta, 'title')->textInput() ?>
< ?= $form->field($model->meta, 'description')->textarea(['rows' => 2]) ?>
< ?= $form->field($model->meta, 'keywords')->textInput() ?>
</div>
</div>
-->
<div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
</div>
<div class="col-md-2">
<div class="box box-default">
<div class="box-header with-border"><?= Yii::t('pages', 'Publish') ?></div>
<div class="box-body">
<div class="btn-group">
<button type="button" class="btn btn-info"><?= Yii::t('pages', 'Preview on site') ?></button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<?php foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name): ?>
<li>
<?= Html::submitButton($language_name, [
'class' => 'btn btn-block btn-flat bg-white',
'value'=>'preview',
'name'=>'submit_preview',
'formaction' => \yii\helpers\Url::to(['/pages/manage/page/create-preview', 'language' => $language == Yii::$app->params['defaultLanguage'] ? '' : $language]),
'formtarget' => '_blank',
'style' => 'border:0; background-color:#ffffff;',
]) ?>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-10">
<div class="box box-default">
<div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div>
<div class="box-body">
<?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?>
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?>
</div>
</div>
<?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">
<?= \yii\bootstrap\Tabs::widget([
'items' => $items
]) ?>
</div>
<div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Save'), ['class' => 'btn btn-success']) ?>
</div>
</div>
<div class="col-md-2">
<div class="box box-default">
<div class="box-header with-border"><?= Yii::t('pages', 'Publish') ?></div>
<div class="box-body">
<div class="btn-group">
<button type="button" class="btn btn-info"><?= Yii::t('pages', 'Preview on site') ?></button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<?php foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) : ?>
<li>
<?= Html::submitButton($language_name, [
'class' => 'btn btn-block btn-flat bg-white',
'value' => 'preview',
'name' => 'submit_preview',
'formaction' => \yii\helpers\Url::to([
'/pages/manage/page/create-preview',
'language' => $language == Yii::$app->params['defaultLanguage'] ? '' : $language
]),
'formtarget' => '_blank',
'style' => 'border:0; background-color:#ffffff;',
]) ?>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
</div>
</div>
<?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 $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'][] = $this->title;
@ -21,104 +21,112 @@ $this->registerCss($css);
<div class="user-view">
<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', 'Delete'), ['delete', 'id' => $page->id], [
'class' => 'btn btn-danger',
'data' => [
'data' => [
'confirm' => Yii::t('buttons', 'Are you sure you want to delete this item?'),
'method' => 'post',
'method' => 'post',
],
]) ?>
</p>
<div class="row">
<div class="col-md-9">
<div class="box">
<div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div>
<div class="box-body">
<?= DetailView::widget([
'model' => $page,
'attributes' => [
'id',
'slug',
],
]) ?>
</div>
</div>
<?php
$items = [];
foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) {
$items[] = [
'label' => $language_name,
'content' => $this->render('_view_tab', [
'page' => $page,
'language' => $language,
]),
];
}
?>
<div class="nav-tabs-custom">
<?= \yii\bootstrap\Tabs::widget([
'items' => $items,
]) ?>
</div>
</div>
<div class="col-md-3">
<div class="box">
<div class="box-header with-border"><?= Yii::t('pages', 'History') ?></div>
<div class="box-body">
<?php if ($history): ?>
<ul>
<?php foreach ($history as $item): ?>
<li>
<?php if ($item->revision_id): ?>
<?= 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])), [
'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',
],
]) ?>
<?php else: ?>
<strong><?= Yii::t('pages', 'Current Edition') ?></strong>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?= Html::a(Yii::t('pages', 'Clear History'), ['/pages/manage/page/clear-history', 'id' => $page->id], [
'class' => 'btn btn-danger btn-sm pull-right',
'data' => [
'confirm' => Yii::t('pages', 'Are you sure you want to remove this history?'),
'method' => 'post',
],
]) ?>
<?php else: ?>
<div style="padding: 20px 0; text-align: center"><?= Yii::t('pages', 'History is empty') ?></div>
<?php endif; ?>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-9">
<div class="box">
<div class="box-header with-border"><?= Yii::t('pages', 'Common') ?></div>
<div class="box-body">
<?= DetailView::widget([
'model' => $page,
'attributes' => [
'id',
'slug',
],
]) ?>
</div>
</div>
<?php
$items = [];
foreach (Yii::$app->params['translatedLanguages'] as $language => $language_name) {
$items[] = [
'label' => $language_name,
'content' => $this->render('_view_tab', [
'page' => $page,
'language' => $language,
]),
];
}
?>
<div class="nav-tabs-custom">
<?= \yii\bootstrap\Tabs::widget([
'items' => $items,
]) ?>
</div>
</div>
<div class="col-md-3">
<div class="box">
<div class="box-header with-border"><?= Yii::t('pages', 'History') ?></div>
<div class="box-body">
<?php if ($history): ?>
<ul>
<?php foreach ($history as $item): ?>
<li>
<?php if ($item->revision_id): ?>
<?= 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
])), [
'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',
],
]) ?>
<?php else: ?>
<strong><?= Yii::t('pages', 'Current Edition') ?></strong>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?= Html::a(Yii::t('pages', 'Clear History'),
['/pages/manage/page/clear-history', 'id' => $page->id], [
'class' => 'btn btn-danger btn-sm pull-right',
'data' => [
'confirm' => Yii::t('pages', 'Are you sure you want to remove this history?'),
'method' => 'post',
],
]) ?>
<?php else: ?>
<div style="padding: 20px 0; text-align: center"><?= Yii::t('pages',
'History is empty') ?></div>
<?php endif; ?>
</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()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
}
$this->createTable(
'{{%settings}}',
[
'id' => $this->primaryKey(),
'type' => $this->string(255)->notNull(),
'section' => $this->string(255)->notNull(),
'key' => $this->string(255)->notNull(),
'value' => $this->text(),
'active' => $this->integer(1),
'created_at' => $this->integer()->unsigned(),
'updated_at' => $this->integer()->unsigned(),
],
$tableOptions
);
$this->createIndex('settings_unique_key_section', '{{%settings}}', ['section', 'key'], true);
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
}
$this->createTable(
'{{%settings}}',
[
'id' => $this->primaryKey(),
'type' => $this->string(255)->notNull(),
'section' => $this->string(255)->notNull(),
'key' => $this->string(255)->notNull(),
'value' => $this->text(),
'active' => $this->integer(1),
'created_at' => $this->integer()->unsigned(),
'updated_at' => $this->integer()->unsigned(),
],
$tableOptions
);
$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()
{
$this->dropIndex('settings_unique_key_section', '{{%settings}}');
$this->dropTable('{{%settings}}');
$this->dropIndex('settings_unique_key_section', '{{%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()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
}
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB';
}
$this->createTable('{{%menu_lng}}', [
'id' => $this->primaryKey(),
'menu_id' => $this->integer()->notNull(),
'language' => $this->string(6)->notNull(),
'name' => $this->string(255)->notNull(),
'id' => $this->primaryKey(),
'menu_id' => $this->integer()->notNull(),
'language' => $this->string(6)->notNull(),
'name' => $this->string(255)->notNull(),
], $tableOptions);
$this->createIndex('idx_menu_lng_language', '{{%menu_lng}}', 'language');
$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->createIndex('idx_menu_lng_language', '{{%menu_lng}}', 'language');
$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');
}
/**
@ -34,9 +34,9 @@ class m180824_081717_create_menu_lng_table extends Migration
*/
public function safeDown()
{
$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_language', '{{%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_language', '{{%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()
{
$tables = ['user_networks', 'settings', 'modules', 'menu', 'menu_items', 'menu_lng', 'menu_items_lng'];
$db = Yii::$app->getDb();
$db->createCommand('SET FOREIGN_KEY_CHECKS=0;')->execute();
$tables = ['user_networks', 'settings', 'modules', 'menu', 'menu_items', 'menu_lng', 'menu_items_lng'];
$db = Yii::$app->getDb();
$db->createCommand('SET FOREIGN_KEY_CHECKS=0;')->execute();
foreach ($tables as $table) {
$db->createCommand( "ALTER TABLE `$table` CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci" )->execute();
}
foreach ($tables as $table) {
$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'
* @var string
* @var array|string
*/
public $relativeField;
@ -91,7 +91,8 @@ class LanguageBehavior extends Behavior
/** @var ActiveRecord $owner */
parent::attach($owner);
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
@ -265,7 +266,14 @@ class LanguageBehavior extends Behavior
/** @var ActiveRecord $translation */
$translation = new $this->virtualClassName;
$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 {
$translation = $translations[$language];
}
@ -315,7 +323,16 @@ class LanguageBehavior extends Behavior
public function getTranslations()
{
/** @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)
@ -327,15 +344,34 @@ class LanguageBehavior extends Behavior
$language = $language ?: \Yii::$app->language;
//}
// if translate exists
$translate = $this->virtualClassName::find()
->andWhere([$this->relativeField => $this->owner->id])
->andWhere([$this->languageField => $language])
->one();
if (is_array($this->relativeField)) {
$condition = [];
foreach ($this->relativeField as $field) {
$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;
return $this->owner->hasOne($this->virtualClassName, [$this->relativeField => $this->_ownerPrimaryKey])
->where([$this->languageField => $language]);
if (is_array($this->relativeField)) {
$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)
@ -343,10 +379,22 @@ class LanguageBehavior extends Behavior
$language = $language ?: $this->defaultLanguage;
//$class = call_user_func(array($this->virtualClassName, 'getInstance'));
return $this->virtualClassName::find()
->andWhere([$this->relativeField => $this->owner->id])
->andWhere([$this->languageField => $language])
->one();
if (is_array($this->relativeField)) {
$condition = [];
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)

24
core/entities/Settings.php

@ -9,9 +9,9 @@ namespace core\entities;
use Yii;
use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior;
use core\behaviors\LanguageBehavior;
/**
* @property integer $id
* @property string $type
* @property string $section
* @property string $key
@ -23,6 +23,8 @@ use yii\behaviors\TimestampBehavior;
class Settings extends ActiveRecord
{
public $_form;
public static function tableName(): string
{
return '{{%settings}}';
@ -31,7 +33,6 @@ class Settings extends ActiveRecord
public function attributeLabels()
{
return [
'id' => Yii::t('main', 'ID'),
'type' => Yii::t('main', 'Type'),
'section' => Yii::t('main', 'Section'),
'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->type = $type;
$settings->section = $section;
$settings->key = $key;
$settings->value = $value;
$settings->active = $active;
$settings->_form = $form;
return $settings;
}
public function edit($type, $section, $key, $value, $active): void
public function edit($form, $type, $section, $key, $active): void
{
$this->type = $type;
$this->section = $section;
$this->key = $key;
$this->value = $value;
$this->active = $active;
$this->_form = $form;
}
public function behaviors(): array
{
return [
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'],
],
];
}
}

227
core/forms/SettingsForm.php

@ -6,122 +6,135 @@
namespace core\forms;
use core\components\LanguageDynamicModel;
use core\entities\Settings;
use yii\base\DynamicModel;
use yii\base\Model;
use yii\helpers\Json;
use yii\base\InvalidParamException;
use Yii;
class SettingsForm extends Model
class SettingsForm extends LanguageDynamicModel
{
public $type;
public $section;
public $key;
public $value;
public $active;
private $_settings;
public $type;
public $section;
public $key;
public $value;
public $active;
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 = [])
{
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);
}
public function attributeLabels()
{
return array_merge(
parent::attributeLabels(),
[
'id' => Yii::t('main', 'ID'),
'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 rules()
{
return [
[['value'], 'string'],
[['section', 'key'], 'string', 'max' => 255],
[
['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 beforeValidate()
{
$validators = $this->getTypes(false);
if (!array_key_exists($this->type, $validators)) {
$this->addError('type', Yii::t('main', 'Please select correct type'));
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 (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;
}
return false;
}
$model = DynamicModel::validateData([
'value' => $this->value
], [
$validators[$this->type],
]);
if ($model->hasErrors()) {
$this->addError('value', $model->getFirstError('value'));
public function attributeLabels()
{
return [
'id' => Yii::t('main', 'ID'),
'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'),
];
}
return false;
}
if ($this->hasErrors()) {
return false;
}
public function 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();
}
return parent::beforeValidate();
}
}

4
core/repositories/SettingsRepository.php

@ -6,9 +6,9 @@ use core\entities\Settings;
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.');
}
return $settings;

12
core/services/SettingsService.php

@ -18,10 +18,10 @@ class SettingsService
public function create(SettingsForm $form): Settings
{
$settings = Settings::create(
$form,
$form->type,
$form->section,
$form->key,
$form->value,
$form->active
);
$this->_repository->save($settings);
@ -29,22 +29,22 @@ class SettingsService
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(
$form,
$form->type,
$form->section,
$form->key,
$form->value,
$form->active
);
$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);
}
}

Loading…
Cancel
Save