Browse Source

Restructure widgets codes

Forms languages
master
Egorka 6 years ago
parent
commit
f82c9c9913
  1. 29
      backend/components/form_builder/assets/FormBuilderAsset.php
  2. 92
      backend/components/form_builder/js/languages/en.lang
  3. 92
      backend/components/form_builder/js/languages/ru.lang
  4. 263
      backend/views/menu/menu.php
  5. 37
      common/behaviors/WidgetContentBehavior.php
  6. 129
      common/modules/banners/views/manage/place/view.php
  7. 104
      common/modules/forms/FormsModule.php
  8. 143
      common/modules/forms/controllers/manage/FormController.php
  9. 41
      common/modules/forms/urls/FormsUrlRule.php
  10. 12
      common/modules/forms/views/manage/form/_form/_form-builder.php
  11. 177
      common/modules/forms/views/manage/form/view.php
  12. 92
      common/modules/pages/PagesModule.php
  13. 76
      common/modules/pages/controllers/PageController.php
  14. 90
      common/modules/pages/entities/Page.php
  15. 84
      common/modules/pages/urls/PageMainUrlRule.php
  16. 41
      frontend/components/FrontendController.php

29
backend/components/form_builder/assets/FormBuilderAsset.php

@ -6,26 +6,25 @@
namespace backend\components\form_builder\assets; namespace backend\components\form_builder\assets;
use yii\jui\JuiAsset; use yii\jui\JuiAsset;
use yii\web\AssetBundle; use yii\web\AssetBundle;
class FormBuilderAsset extends AssetBundle class FormBuilderAsset extends AssetBundle
{ {
public $sourcePath = '@backend/components/form_builder'; public $sourcePath = '@backend/components/form_builder';
public $js = [ public $js = [
'js/form-builder.min.js', 'js/form-builder.min.js',
'js/form-render.min.js' 'js/form-render.min.js'
]; ];
public $depends = [ public $depends = [
'yii\web\YiiAsset', 'yii\web\YiiAsset',
'yii\bootstrap\BootstrapPluginAsset', 'yii\bootstrap\BootstrapPluginAsset',
JuiAsset::class, JuiAsset::class,
]; ];
public $publishOptions = [ public $publishOptions = [
'forceCopy' => YII_ENV_DEV ? true : false, 'forceCopy' => YII_ENV_DEV ? true : false,
]; ];
} }

92
backend/components/form_builder/js/languages/en.lang

@ -0,0 +1,92 @@
addOption = Add option
allFieldsRemoved = Allfields deleted
allowSelect = Allow select
autocomplete = Autocomplete
button = Button
cannotBeEmpty = This field cannot be empty
checkboxGroup = Checkbox group
checkbox = Checkbox
checkboxes = Checkboxes
class = Class
clearAllMessage = Are you sure, clear all fields?
clear = Clear
close = Close
content = Content
copy = Copy
dateField = Date field
description = Hint
descriptionField = Description
devMode = Debug mode
editNames = Edit names
editorTitle = Form elements
editXML = Edit XML
fieldDeleteWarning: false
fieldVars = Variable fields
fieldNonEditable = Non editable field
fieldRemoveWarning = Are you sure, delete this field?
fileUpload = Upload
formUpdated = Form updated
getStarted = Drag field from right side here
header = Header
hide = Edit
hidden = Hidden field
label = Label
labelEmpty = Label cannot be empty
limitRole = Deny access for one/some roles:
mandatory = Required
maxlength = Max length
minOptionMessage = Select more then 1 options for this field
name = Name
no = No
off = Off
on = On
option = Option
optional = Optional
optionEmpty = Option must have a value
paragraph = Paragraph
placeholder = Placeholder
placeholder.value = Value
placeholder.label = Label
placeholder.text = Enter anything
placeholder.textarea = Enter a text
placeholder.email = Enter your EMAIL
placeholder.placeholder = Placeholder
placeholder.className = Class names divided by spaces
placeholder.password = Enter you password
preview = Preview
radioGroup = Radio group
radio = Radio
removeMessage = Delete element
remove = ×
required = Required
richText = Text editor
roles = Roles
save = Save
selectOptions = Options
select = Select
selectColor = Select color
selectionsMessage = Multiselection enabled
size = Size
sizes = Sizes
sizes.xs = Very small
sizes.sm = Small
sizes.m = Default
sizes.lg = Big
style = Style
styles = Styles
styles.btn = Button style
styles.btn.default = Default
styles.btn.danger = Danger!
styles.btn.info = Info
styles.btn.primary = Primary
styles.btn.success = Success
styles.btn.warning = Warning
subtype = Type
text = Text field
textArea = Textarea
toggle = Toggle
value = Value
warning = Warning!
viewXML = </>
viewJSON = { }
yes = Yes

92
backend/components/form_builder/js/languages/ru.lang

@ -0,0 +1,92 @@
addOption = Добавить опцию
allFieldsRemoved = Все поля удалены
allowSelect = Позволить выбор
autocomplete = Автозаполнение
button = Кнопка
cannotBeEmpty = Данное поле не может быть пустым
checkboxGroup = Группа Чекбоксов
checkbox = Чекбокс
checkboxes = Чекбоксы
class = Класс
clearAllMessage = Вы уверены, что хотите очистить все поля?
clear = Очистить
close = Закрыть
content = Содержимое
copy = Копировать в буфер
dateField = Поле Дата
description = Подсказка
descriptionField = Описание
devMode = Режим отладки
editNames = Редактировать Имена
editorTitle = Элементы формы
editXML = Редактировать XML
fieldDeleteWarning: ложь
fieldVars = Переменные Поля
fieldNonEditable = Данное поле не является редактируемым
fieldRemoveWarning = Вы уверены, что хотите удалить данное поле?
fileUpload = Загрузка файла
formUpdated = Форма обновлена
getStarted = Перетащите поле из правой области в эту зону
header = Заголовок
hide = Редактировать
hidden = Скрытое поле ввода
label = Метка
labelEmpty = Метка поля не может быть пустой
limitRole = Ограниченный доступ к одной или нескольким из следующих ролей:
mandatory = Обязательно
maxlength = Максимальная длина
minOptionMessage = Данное поле требует указания хотя бы 2-х опций
name = Имя
no = Нет
off = Выкл.
on = Вкл.
option = Опция
optional = Опциональный
optionEmpty = Требуется значение опции
paragraph = Параграф
placeholder = Заглушка
placeholder.value = Значение
placeholder.label = Метка
placeholder.text = Введите что-нибудь
placeholder.textarea = Введите много текста
placeholder.email = Введите Ваш EMAIL
placeholder.placeholder = Заглушка
placeholder.className = Имена классов, разделенные пробелами
placeholder.password = Введите Ваш пароль
preview = Предосмотр
radioGroup = Группа радио-контролов
radio = Радио-контрол
removeMessage = Удалить элемент
remove = ×
required = Требуется
richText = Редактор текста
roles = Доступ
save = Сохранить
selectOptions = Опции
select = Выбрать
selectColor = Выбрать цвет
selectionsMessage = Множественный выбор включен
size = Размер
sizes = Размеры
sizes.xs = Очень маленький
sizes.sm = Маленький
sizes.m = По умолчанию
sizes.lg = Большой
style = Стиль
styles = Стили
styles.btn = Стиль кнопки
styles.btn.default = По умолчанию
styles.btn.danger = Опасно!
styles.btn.info = Информация
styles.btn.primary = Главная
styles.btn.success = Удачный
styles.btn.warning = Предупреждение
subtype = Тип
text = Текстовое поле
textArea = Поле текста
toggle = Переключатель
value = Значение
warning = Внимание!
viewXML = </>
viewJSON = { }
yes = Да

263
backend/views/menu/menu.php

@ -5,7 +5,6 @@
*/ */
use kartik\form\ActiveForm; use kartik\form\ActiveForm;
use yii\helpers\ArrayHelper;
use yii\helpers\Html; use yii\helpers\Html;
/** /**
@ -16,124 +15,156 @@ use yii\helpers\Html;
* @var $creator array * @var $creator array
*/ */
$this->title = Yii::t('menu', 'Menu'); $this->title = Yii::t('menu', 'Menu');
$this->params['breadcrumbs'][] = Html::encode(isset($menu->translation) ? $menu->translation->name : Yii::t('menu', 'Not set')); $this->params['breadcrumbs'][] = Html::encode(isset($menu->translation) ? $menu->translation->name : Yii::t('menu', 'Not set'));
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
$js2 = <<<JS2
$("#copyEditorCodeButton").on('click', function(){
CopyToClipboard($('#code_editor'));
});
$("#copyTemplateCodeButton").on('click', function(){
CopyToClipboard($('#code_template'));
});
JS2;
$this->registerJs($js2, $this::POS_READY);
$js = <<<JS
function CopyToClipboard(selector) {
var body = $("body");
selector.select();
document.execCommand("copy");
}
JS;
$this->registerJs($js, $this::POS_HEAD);
?> ?>
<div class="menu"> <div class="menu">
<div class="box box-default"> <div class="box box-default">
<div class="box-header with-border"><?= Yii::t('menu', 'Current Menu') ?></div> <div class="box-header with-border"><?= Yii::t('menu', 'Current Menu') ?></div>
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<?php $form = ActiveForm::begin([ <?php $form = ActiveForm::begin([
'enableClientValidation' => false, 'enableClientValidation' => false,
'method' => 'get', 'method' => 'get',
'id' => 'select_menu', 'id' => 'select_menu',
]); ?> ]); ?>
<?= $form->field($model, 'id')->dropDownList($menus, [ <?= $form->field($model, 'id')->dropDownList($menus, [
//'prompt' => Yii::t('menu', 'Select menu...'), //'prompt' => Yii::t('menu', 'Select menu...'),
'value' => $menu->id, 'value' => $menu->id,
'onchange' => 'this.form.submit()', 'onchange' => 'this.form.submit()',
])->label(false) ?> ])->label(false) ?>
<?php ActiveForm::end(); ?> <?php ActiveForm::end(); ?>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<?= Html::a(Yii::t('menu', 'Create Menu'), ['menu/create'], [ <?= Html::a(Yii::t('menu', 'Create Menu'), ['menu/create'], [
'class' => 'btn btn-success', 'class' => 'btn btn-success',
]) ?> ]) ?>
<?= Html::a(Yii::t('menu', 'Update Menu'), ['menu/update', 'id' => $menu->id], [ <?= Html::a(Yii::t('menu', 'Update Menu'), ['menu/update', 'id' => $menu->id], [
'class' => 'btn btn-primary', 'class' => 'btn btn-primary',
]) ?> ]) ?>
<?= Html::a(Yii::t('menu', 'Delete Menu'), ['menu/delete', 'id' => $menu->id], [ <?= Html::a(Yii::t('menu', 'Delete Menu'), ['menu/delete', 'id' => $menu->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',
], ],
]) ?> ]) ?>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<div class="box box-default"> <div class="box box-default">
<div class="box-header with-border"><?= Yii::t('menu', 'Available Blocks') ?></div> <div class="box-header with-border"><?= Yii::t('menu', 'Available Blocks') ?></div>
<div class="box-body"> <div class="box-body">
<div class="panel-group" id="accordion"> <div class="panel-group" id="accordion">
<?php foreach ($creator as $item): ?> <?php foreach ($creator as $item) : ?>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading" style="padding-left: 0"> <div class="panel-heading" style="padding-left: 0">
<h4 class="panel-title"> <h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse<?= $item['id'] ?>"><?= $item['title'] ?> <a data-toggle="collapse" data-parent="#accordion"
<i class="fa fa-angle-down pull-right" aria-hidden="true"></i></a> href="#collapse<?= $item['id'] ?>"><?= $item['title'] ?>
</h4> <i class="fa fa-angle-down pull-right" aria-hidden="true"></i></a>
</div> </h4>
<div id="collapse<?= $item['id'] ?>" class="panel-collapse collapse"> </div>
<div class="panel-body"> <div id="collapse<?= $item['id'] ?>" class="panel-collapse collapse">
<?= $item['content'] ?> <div class="panel-body">
</div> <?= $item['content'] ?>
</div> </div>
</div> </div>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
</div>
</div>
</div> </div>
</div> </div>
<div class="col-md-6"> </div>
<div class="box box-default"> <div class="col-md-6">
<div class="box-header with-border"><?= Yii::t('menu', 'Menu Items') ?></div> <div class="box box-default">
<div class="box-body"> <div class="box-header with-border"><?= Yii::t('menu', 'Menu Items') ?></div>
<div class="box-body">
<?= \backend\components\menu\widgets\MenuEditorWidget::widget([
'menu_id' => $menu->id <?= \backend\components\menu\widgets\MenuEditorWidget::widget([
]) ?> 'menu_id' => $menu->id
]) ?>
</div>
</div> </div>
</div> </div>
</div>
<div class="col-md-3">
<div class="box box-default"> <div class="col-md-3">
<div class="box-header with-border"><?= Yii::t('menu', 'Insert Code') ?></div> <div class="box box-default">
<div class="box-body"> <div class="box-header with-border"><?= Yii::t('menu', 'Insert Code') ?></div>
<div class="box-body">
<?php
$code = Html::encode( <?php
"<?= \core\widgets\menu\MenuWidget::widget([ $code = "<?= \core\widgets\menu\MenuWidget::widget(['menu_id' => " . $menu->id . ']) ?>';
'menu_id' => ".$menu->id.", ?>
]) ?>"); <p><?= Yii::t('menu', 'For template') ?></p>
?> <div class="input-group">
<p><?= Yii::t('menu', 'For template') ?></p> <?= Html::input('text', 'code_template', $code, [
<pre><?= $code ?></pre> 'class' => 'form-control',
'id' => 'code_template',
<?php ]) ?>
$code = Html::encode( <span class="input-group-btn">
"[?= \core\widgets\menu\MenuWidget::widget([ <button id="copyTemplateCodeButton" type="button" class="btn btn-primary btn-flat"><i class="fa fa-files-o" aria-hidden="true"></i></button>
'menu_id' => ".$menu->id.", </span>
]) ?]"); </div>
?>
<p><?= Yii::t('menu', 'For editor') ?></p> <?php
<pre><?= $code ?></pre> $code = "[?= \core\widgets\menu\MenuWidget::widget(['menu_id' => " . $menu->id . ']) ?]';
</div> ?>
</div> <p><?= Yii::t('menu', 'For editor') ?></p>
</div> <div class="input-group">
<?= Html::input('text', 'code_editor', $code, [
'class' => 'form-control',
</div> 'id' => 'code_editor',
]) ?>
<span class="input-group-btn">
<button id="copyEditorCodeButton" type="button" class="btn btn-primary btn-flat"><i class="fa fa-files-o" aria-hidden="true"></i></button>
</span>
</div>
</div>
</div>
</div>
</div>

37
common/behaviors/WidgetContentBehavior.php

@ -11,20 +11,23 @@ use yii\base\Behavior;
class WidgetContentBehavior extends Behavior class WidgetContentBehavior extends Behavior
{ {
/** /**
* Parse Widgets [?= ... ?] * Parse Widgets #?= ... ?#
* @param $text *
* * @param $text
* @return string *
*/ * @return string
public function content($text): string */
{ public function content($text): string
$content = preg_replace_callback('/\[\?= (.*)\((.*)\) \?\]/m', function ($m) { {
$array = []; $content = preg_replace_callback('/\[\?= (.*)\((.*)\) \?\]/m', function ($m) {
$string = Html::decode( $m[2] ); $array = [];
eval( "\$array = $string;" ); $string = Html::decode($m[2]);
return $m[1]( $array ); eval("\$array = $string;");
}, $text);
return $content; return $m[1]($array);
} }, $text);
}
return $content;
}
}

129
common/modules/banners/views/manage/place/view.php

@ -8,69 +8,104 @@ use common\modules\banners\helpers\BannerHelper;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $place \common\modules\banners\entities\BannerPlace */ /* @var $place \common\modules\banners\entities\BannerPlace */
$this->title = $place->title; $this->title = $place->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Places'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('banners', 'Places'), 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
$js2 = <<<JS2
$("#copyEditorCodeButton").on('click', function(){
CopyToClipboard($('#code_editor'));
});
$("#copyTemplateCodeButton").on('click', function(){
CopyToClipboard($('#code_template'));
});
JS2;
$this->registerJs($js2, $this::POS_READY);
$js = <<<JS
function CopyToClipboard(selector) {
var body = $("body");
selector.select();
document.execCommand("copy");
}
JS;
$this->registerJs($js, $this::POS_HEAD);
?> ?>
<div class="place-view"> <div class="place-view">
<p> <p>
<?= Html::a(Yii::t('banners','Places'), ['index'], ['class' => 'btn btn-default']) ?> <?= Html::a(Yii::t('banners', 'Places'), ['index'], ['class' => 'btn btn-default']) ?>
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $place->id], ['class' => 'btn btn-primary']) ?> <?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $place->id], ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $place->id], [ <?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $place->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-body">
<?= DetailView::widget([
'model' => $place,
'attributes' => [
'id',
'title',
'width',
'height',
[
'attribute' => 'active',
'format' => 'raw',
'value' => function (BannerPlace $place) {
return BannerHelper::statusLabel($place->active);
}
],
],
]) ?>
</div>
</div>
</div>
<div class="box"> <div class="col-md-3">
<div class="box-body"> <div class="box box-default">
<?= DetailView::widget([ <div class="box-header with-border"><?= Yii::t('banners', 'Insert Code') ?></div>
'model' => $place, <div class="box-body">
'attributes' => [
'id',
'title',
'width',
'height',
[
'attribute' => 'active',
'format' => 'raw',
'value' => function(BannerPlace $place) {
return BannerHelper::statusLabel($place->active);
}
],
],
]) ?>
</div>
</div>
</div>
<div class="col-md-3"> <?php
<div class="box box-default"> $code = "<?= \common\modules\\banners\widgets\BannerWidget::widget(['id' => " . $place->id . ']) ?>';
<div class="box-header with-border"><?= Yii::t('banners', 'Insert Code') ?></div> ?>
<div class="box-body"> <p><?= Yii::t('banners', 'For template') ?></p>
<div class="input-group">
<?= Html::input('text', 'code_template', $code, [
'class' => 'form-control',
'id' => 'code_template',
]) ?>
<span class="input-group-btn">
<button id="copyTemplateCodeButton" type="button" class="btn btn-primary btn-flat"><i class="fa fa-files-o" aria-hidden="true"></i></button>
</span>
</div>
<?php <?php
$code = Html::encode( $code = "[?= \common\modules\\banners\widgets\BannerWidget::widget(['id' => " . $place->id . ']) ?]';
"<?= \common\modules\\banners\widgets\BannerWidget::widget(['id' => ".$place->id."]) ?>"); ?>
?> <p><?= Yii::t('banners', 'For editor') ?></p>
<p><?= Yii::t('banners', 'For template') ?></p> <div class="input-group">
<pre><?= $code ?></pre> <?= Html::input('text', 'code_editor', $code, [
'class' => 'form-control',
'id' => 'code_editor',
]) ?>
<span class="input-group-btn">
<button id="copyEditorCodeButton" type="button" class="btn btn-primary btn-flat"><i class="fa fa-files-o" aria-hidden="true"></i></button>
</span>
</div>
<?php </div>
$code = Html::encode( </div>
"[?= \common\modules\\banners\widgets\BannerWidget::widget(['id' => ".$place->id."]) ?]"); </div>
?> </div>
<p><?= Yii::t('banners', 'For editor') ?></p>
<pre><?= $code ?></pre>
</div>
</div>
</div>
</div>
</div> </div>

104
common/modules/forms/FormsModule.php

@ -2,12 +2,10 @@
namespace common\modules\forms; namespace common\modules\forms;
use common\modules\forms\entities\Form;
use common\modules\forms\entities\FormMessage; use common\modules\forms\entities\FormMessage;
use common\modules\forms\urls\FormsUrlRule;
use core\components\modules\ModuleInterface; use core\components\modules\ModuleInterface;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\helpers\Html;
/** /**
* blog module definition class * blog module definition class
@ -29,56 +27,60 @@ class FormsModule extends \yii\base\Module implements ModuleInterface
// custom initialization code goes here // custom initialization code goes here
} }
public function bootstrap($app) public function bootstrap($app)
{ {
// add migration path // add migration path
$app->controllerMap['migrate']['migrationPath'][] = '@common/modules/forms/migrations'; $app->controllerMap['migrate']['migrationPath'][] = '@common/modules/forms/migrations';
// prepare rules
//$app->getUrlManager()->addRules([
// 'forms/manage/form/view/<id:\d+>' => 'forms/manage/form/view',
//]);
// prepare rules $app->getUrlManager()->addRules([
$app->getUrlManager()->addRules([ ['class' => FormsUrlRule::class],
'forms/manage/form/view/<id:\d+>' => 'forms/manage/form/view', ]);
]);
// add languages // add languages
$app->getI18n()->translations = ArrayHelper::merge($app->getI18n()->translations, [ $app->getI18n()->translations = ArrayHelper::merge($app->getI18n()->translations, [
'forms' => [ 'forms' => [
'class' => 'yii\i18n\PhpMessageSource', 'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@common/modules/forms/messages', 'basePath' => '@common/modules/forms/messages',
], ],
]); ]);
// add menu items // add menu items
if (basename($app->getBasePath()) === 'backend') { if (basename($app->getBasePath()) === 'backend') {
$app->params['adminMenu'][] = [ $app->params['adminMenu'][] = [
'label' => \Yii::t( 'forms', 'Forms' ), 'label' => \Yii::t('forms', 'Forms'),
'icon' => 'address-card-o', 'icon' => 'address-card-o',
'items' => [ 'items' => [
[ [
'label' => \Yii::t( 'forms', 'Forms' ), 'label' => \Yii::t('forms', 'Forms'),
'icon' => 'caret-right', 'icon' => 'caret-right',
'url' => [ '/forms/manage/form/index' ] 'url' => ['/forms/manage/form/index']
], ],
[ [
'label' => \Yii::t( 'forms', 'Messages' ), 'label' => \Yii::t('forms', 'Messages'),
'icon' => 'caret-right', 'icon' => 'caret-right',
'url' => [ '/forms/manage/form-message/index' ] 'url' => ['/forms/manage/form-message/index']
], ],
], ],
'visible' => \Yii::$app->user->can( 'admin' ) || \Yii::$app->user->can( 'FormsManagement' ), 'visible' => \Yii::$app->user->can('admin') || \Yii::$app->user->can('FormsManagement'),
]; ];
} }
// prepare notifications // prepare notifications
$new_messages_count = \Yii::$app->moduleManager->isTableExist('{{%forms}}') ? FormMessage::find()->unread()->count() : 0; $new_messages_count = \Yii::$app->moduleManager->isTableExist('{{%forms}}') ? FormMessage::find()->unread()->count() : 0;
if ($new_messages_count > 0) { if ($new_messages_count > 0) {
$app->params['notifications'][] = [ $app->params['notifications'][] = [
'icon' => 'address-card-o', 'icon' => 'address-card-o',
'color' => 'yellow', 'color' => 'yellow',
'message' => 'New forms messages: {count}', 'message' => 'New forms messages: {count}',
'message_file' => 'forms', 'message_file' => 'forms',
'url' => '/forms/manage/form-message/index', 'url' => '/forms/manage/form-message/index',
'count' => $new_messages_count, 'count' => $new_messages_count,
]; ];
} }
} }
} }

143
common/modules/forms/controllers/manage/FormController.php

@ -7,7 +7,6 @@ use common\modules\forms\forms\FormSearch;
use common\modules\forms\entities\Form; use common\modules\forms\entities\Form;
use common\modules\pages\entities\Page; use common\modules\pages\entities\Page;
use common\modules\forms\forms\FormForm; use common\modules\forms\forms\FormForm;
use yii\helpers\Json;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -17,32 +16,32 @@ use Yii;
class FormController extends Controller class FormController extends Controller
{ {
private $service; private $_service;
public function __construct($id, $module, FormManageService $service, $config = []) public function __construct($id, $module, FormManageService $service, $config = [])
{ {
parent::__construct($id, $module, $config); parent::__construct($id, $module, $config);
$this->service = $service; $this->_service = $service;
} }
public function behaviors(): array public function behaviors(): array
{ {
return [ return [
'access' => [ 'access' => [
'class' => AccessControl::class, 'class' => AccessControl::class,
'rules' => [ 'rules' => [
[ [
'allow' => true, 'allow' => true,
'roles' => ['FormsManagement'], 'roles' => ['FormsManagement'],
], ],
[ // all the action are accessible to admin [ // all the action are accessible to admin
'allow' => true, 'allow' => true,
'roles' => ['admin'], 'roles' => ['admin'],
], ],
], ],
], ],
'verbs' => [ 'verbs' => [
'class' => VerbFilter::class, 'class' => VerbFilter::class,
'actions' => [ 'actions' => [
'delete' => ['POST'], 'delete' => ['POST'],
], ],
@ -55,21 +54,21 @@ class FormController extends Controller
*/ */
public function actionIndex() public function actionIndex()
{ {
$searchModel = new FormSearch(); $searchModel = new FormSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [ return $this->render('index', [
'searchModel' => $searchModel, 'searchModel' => $searchModel,
'dataProvider' => $dataProvider, 'dataProvider' => $dataProvider,
]); ]);
} }
/** /**
* @param $id * @param $id
* *
* @return string * @return string
* @throws NotFoundHttpException * @throws NotFoundHttpException
*/ */
public function actionView($id) public function actionView($id)
{ {
return $this->render('view', [ return $this->render('view', [
@ -85,7 +84,8 @@ class FormController extends Controller
$form = new FormForm(); $form = new FormForm();
if ($form->load(Yii::$app->request->post()) && $form->validate()) { if ($form->load(Yii::$app->request->post()) && $form->validate()) {
try { try {
$form = $this->service->create($form); $form = $this->_service->create($form);
return $this->redirect(['view', 'id' => $form->id]); return $this->redirect(['view', 'id' => $form->id]);
} catch (\DomainException $e) { } catch (\DomainException $e) {
Yii::$app->errorHandler->logException($e); Yii::$app->errorHandler->logException($e);
@ -98,12 +98,12 @@ class FormController extends Controller
]); ]);
} }
/** /**
* @param $id * @param $id
* *
* @return string|\yii\web\Response * @return string|\yii\web\Response
* @throws NotFoundHttpException * @throws NotFoundHttpException
*/ */
public function actionUpdate($id) public function actionUpdate($id)
{ {
$form_model = $this->findModel($id); $form_model = $this->findModel($id);
@ -111,7 +111,8 @@ class FormController extends Controller
$form = new FormForm($form_model); $form = new FormForm($form_model);
if ($form->load(Yii::$app->request->post()) && $form->validate()) { if ($form->load(Yii::$app->request->post()) && $form->validate()) {
try { try {
$this->service->edit($form_model->id, $form); $this->_service->edit($form_model->id, $form);
return $this->redirect(['view', 'id' => $form_model->id]); return $this->redirect(['view', 'id' => $form_model->id]);
} catch (\DomainException $e) { } catch (\DomainException $e) {
Yii::$app->errorHandler->logException($e); Yii::$app->errorHandler->logException($e);
@ -120,48 +121,82 @@ class FormController extends Controller
} }
return $this->render('update', [ return $this->render('update', [
'model' => $form, 'model' => $form,
'form_model' => $form_model, 'form_model' => $form_model,
]); ]);
} }
/** /**
* @param integer $id * @param integer $id
*
* @return mixed * @return mixed
*/ */
public function actionDelete($id) public function actionDelete($id)
{ {
try { try {
$this->service->remove($id); $this->_service->remove($id);
} 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());
} }
return $this->redirect(['index']); return $this->redirect(['index']);
} }
public function actionPageSearch($q = null, $id = null) public function actionPageSearch($q = null, $id = null)
{ {
\Yii::$app->response->format = Response::FORMAT_JSON; \Yii::$app->response->format = Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']]; $out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) { if (!is_null($q)) {
$data = Page::find()->select('id, title as text')->andWhere(['tree' => 1])->andWhere(['like', 'title', $q])->limit(20)->asArray()->all(); $data = [];
$out['results'] = array_values($data); $pages = Page::find()
} ->with('translation')
elseif ($id > 0) { ->leftJoin('{{%pages_lng}}', '`pages_lng`.`page_id` = `pages`.`id`')
$tag_name = Page::findOne($id)->title; ->andWhere(['like', 'pages_lng.title', $q])
$out['results'] = ['id' => $tag_name, 'text' => $tag_name]; ->limit(20)
} ->all();
else { foreach ($pages as $page) {
$data = Page::find()->select('id, title as text')->andWhere(['tree' => 1])->orderBy(['id' => SORT_DESC])->limit(20)->asArray()->all(); $data[] = [
$out['results'] = array_values($data); 'id' => $page->id,
} 'text' => isset($page->translation) ? $page->translation->title : null,
return $out; ];
} }
$out['results'] = array_values($data);
} elseif ($id > 0) {
$tag_name = Page::findOne($id)->translation->title;
$out['results'] = ['id' => $tag_name, 'text' => $tag_name];
} else {
/*$data = [];
$pages = Page::find()
->with('translation')
->leftJoin('{{%pages_lng}}', '`pages_lng`.`page_id` = `pages`.`id`')
->limit(20)
->all();
foreach ($pages as $page) {
$data[] = [
'id' => $page->id,
'text' => isset($page->translation) ? $page->translation->title : null,
];
}*/
$data = [];
$pages = Page::find()->typePublic()->orderBy(['id' => SORT_DESC])->limit(20)->all();
foreach ($pages as $page) {
$data[] = [
'id' => $page->id,
'text' => isset($page->translation) ? $page->translation->title : null,
];
}
$out['results'] = array_values($data);
}
return $out;
}
/** /**
* @param integer $id * @param integer $id
*
* @return Form the loaded model * @return Form the loaded model
* @throws NotFoundHttpException if the model cannot be found * @throws NotFoundHttpException if the model cannot be found
*/ */

41
common/modules/forms/urls/FormsUrlRule.php

@ -0,0 +1,41 @@
<?php
namespace common\modules\forms\urls;
use common\modules\forms\repositories\FormRepository;
use core\helpers\LanguageHelper;
use yii\base\BaseObject;
use yii\web\UrlRuleInterface;
use yii;
class FormsUrlRule extends BaseObject implements UrlRuleInterface
{
public $prefix = 'forms/form/send';
private $_repository;
public function __construct(FormRepository $repository, array $config = [])
{
parent::__construct($config);
$this->_repository = $repository;
}
public function parseRequest($manager, $request)
{
$uri = ltrim(LanguageHelper::processLangInUrl($request->pathInfo), '/');
if ($uri == $this->prefix) {
$id = Yii::$app->request->get('id');
$form = $this->_repository->get($id);
if ($form) {
return [$uri, ['id' => $id]];
}
}
return false;
}
public function createUrl($manager, $route, $params)
{
return false;
}
}

12
common/modules/forms/views/manage/form/_form/_form-builder.php

@ -10,11 +10,14 @@ use \yii\helpers\Json;
* @var $this \yii\web\View * @var $this \yii\web\View
* @var $model \common\modules\forms\forms\FormForm * @var $model \common\modules\forms\forms\FormForm
*/ */
\backend\components\form_builder\assets\FormBuilderAsset::register($this); $bundle = \backend\components\form_builder\assets\FormBuilderAsset::register($this);
$lng = str_replace('_', '-', Yii::$app->language); $lng = str_replace('_', '-', Yii::$app->language);
$lng_file = $bundle->baseUrl . '/js/languages/';
$data = $model->data ? Json::encode($model->data, JSON_UNESCAPED_UNICODE) : '[]'; $data = $model->data ? Json::encode($model->data, JSON_UNESCAPED_UNICODE) : '[]';
$js = <<<JS
$js = <<<JS
var options = { var options = {
controlOrder: [ controlOrder: [
'text', 'text',
@ -25,7 +28,8 @@ $js = <<<JS
'number', 'autocomplete', 'date', 'file' 'number', 'autocomplete', 'date', 'file'
], ],
i18n: { i18n: {
locale: '{$lng}' locale: '{$lng}',
location: '{$lng_file}'
}, },
showActionButtons: false, showActionButtons: false,
formData: {$data}, formData: {$data},
@ -74,6 +78,6 @@ $this->registerCss($css);
?> ?>
<div class="form-builder-container" style="padding: 20px; overflow: auto"> <div class="form-builder-container" style="padding: 20px; overflow: auto">
<div id="fb-editor"></div> <div id="fb-editor"></div>
</div> </div>

177
common/modules/forms/views/manage/form/view.php

@ -8,90 +8,125 @@ use common\modules\forms\helpers\FormHelper;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $form Form */ /* @var $form Form */
$this->title = $form->name; $this->title = $form->name;
$this->params['breadcrumbs'][] = ['label' => Yii::t('forms', 'Forms'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('forms', 'Forms'), 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title; $this->params['breadcrumbs'][] = $this->title;
$js2 = <<<JS2
$("#copyEditorCodeButton").on('click', function(){
CopyToClipboard($('#code_editor'));
});
$("#copyTemplateCodeButton").on('click', function(){
CopyToClipboard($('#code_template'));
});
JS2;
$this->registerJs($js2, $this::POS_READY);
$js = <<<JS
function CopyToClipboard(selector) {
var body = $("body");
selector.select();
document.execCommand("copy");
}
JS;
$this->registerJs($js, $this::POS_HEAD);
?> ?>
<div class="form-view"> <div class="form-view">
<p> <p>
<?= Html::a(Yii::t('forms','Forms'), ['index'], ['class' => 'btn btn-default']) ?> <?= Html::a(Yii::t('forms', 'Forms'), ['index'], ['class' => 'btn btn-default']) ?>
<?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $form->id], ['class' => 'btn btn-primary']) ?> <?= Html::a(Yii::t('buttons', 'Edit'), ['update', 'id' => $form->id], ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $form->id], [ <?= Html::a(Yii::t('buttons', 'Delete'), ['delete', 'id' => $form->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('forms', 'Common') ?></div> <div class="box-header with-border"><?= Yii::t('forms', 'Common') ?></div>
<div class="box-body"> <div class="box-body">
<?= DetailView::widget([ <?= DetailView::widget([
'model' => $form, 'model' => $form,
'attributes' => [ 'attributes' => [
'id', 'id',
'name', 'name',
'subject', 'subject',
'from', 'from',
'reply', 'reply',
'return', 'return',
[ [
'attribute' => 'status', 'attribute' => 'status',
'format' => 'raw', 'format' => 'raw',
'value' => function(Form $form) { 'value' => function (Form $form) {
return FormHelper::statusLabel($form->status); return FormHelper::statusLabel($form->status);
} }
], ],
'captcha', 'captcha',
'complete_page_id' 'complete_page_id'
], ],
]) ?> ]) ?>
</div> </div>
</div> </div>
<div class="box"> <div class="box">
<div class="box-header with-border"><?= Yii::t('forms', 'Complete Message') ?></div> <div class="box-header with-border"><?= Yii::t('forms', 'Complete Message') ?></div>
<div class="box-body"> <div class="box-body">
<?= Yii::$app->formatter->asHtml($form->complete_text, [ <?= Yii::$app->formatter->asHtml($form->complete_text, [
'Attr.AllowedRel' => array('nofollow'), 'Attr.AllowedRel' => ['nofollow'],
'HTML.SafeObject' => true, 'HTML.SafeObject' => true,
'Output.FlashCompat' => true, 'Output.FlashCompat' => true,
'HTML.SafeIframe' => true, 'HTML.SafeIframe' => true,
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%', 'URI.SafeIframeRegexp' => '%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%',
]) ?> ]) ?>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="box box-default"> <div class="box box-default">
<div class="box-header with-border"><?= Yii::t('forms', 'Insert Code') ?></div> <div class="box-header with-border"><?= Yii::t('forms', 'Insert Code') ?></div>
<div class="box-body"> <div class="box-body">
<?php <?php
$code = Html::encode( $code = "<?= \common\modules\\forms\widgets\FormWidget::widget(['id' => " . $form->id . ']) ?>';
"<?= \common\modules\\forms\widgets\FormWidget::widget(['id' => ".$form->id."]) ?>"); ?>
?> <p><?= Yii::t('forms', 'For template') ?></p>
<p><?= Yii::t('forms', 'For template') ?></p> <div class="input-group">
<pre><?= $code ?></pre> <?= Html::input('text', 'code_template', $code, [
'class' => 'form-control',
<?php 'id' => 'code_template',
$code = Html::encode( ]) ?>
"[?= \common\modules\\forms\widgets\FormWidget::widget(['id' => ".$form->id."]) ?]"); <span class="input-group-btn">
?> <button id="copyTemplateCodeButton" type="button" class="btn btn-primary btn-flat"><i class="fa fa-files-o" aria-hidden="true"></i></button>
<p><?= Yii::t('menu', 'For editor') ?></p> </span>
<pre><?= $code ?></pre> </div>
</div>
</div> <?php
</div> $code = "[?= \common\modules\\forms\widgets\FormWidget::widget(['id' => " . $form->id . ']) ?]';
?>
</div> <p><?= Yii::t('menu', 'For editor') ?></p>
<div class="input-group">
<?= Html::input('text', 'code_editor', $code, [
'class' => 'form-control',
'id' => 'code_editor',
]) ?>
<span class="input-group-btn">
<button id="copyEditorCodeButton" type="button" class="btn btn-primary btn-flat"><i class="fa fa-files-o" aria-hidden="true"></i></button>
</span>
</div>
</div>
</div>
</div>
</div>
</div> </div>

92
common/modules/pages/PagesModule.php

@ -6,7 +6,6 @@ use common\modules\pages\widgets\MenuItemCreatorWidget;
use core\components\modules\ModuleInterface; use core\components\modules\ModuleInterface;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
/** /**
* page module definition class * page module definition class
*/ */
@ -27,57 +26,58 @@ class PagesModule extends \yii\base\Module implements ModuleInterface
// custom initialization code goes here // custom initialization code goes here
} }
public function bootstrap($app) public function bootstrap($app)
{ {
// add migration path // add migration path
$app->controllerMap['migrate']['migrationPath'][] = '@common/modules/pages/migrations'; $app->controllerMap['migrate']['migrationPath'][] = '@common/modules/pages/migrations';
// add search rules // add search rules
$app->params['search_rules'][] = " $app->params['search_rules'][] = "
SELECT title, content, CONCAT('/pages/manage/page/view/', page_id) AS url FROM {{pages_lng}} SELECT title, content, CONCAT('/pages/manage/page/view/', page_id) AS url FROM {{pages_lng}}
"; ";
$app->getUrlManager()->addRules([ $app->getUrlManager()->addRules([
['class' => 'common\modules\pages\urls\PageMainUrlRule'], ['class' => 'common\modules\pages\urls\PageMainUrlRule'],
]); ]);
$app->getUrlManager()->addRules([
'pages/manage/page/view/<id:\d+>' => 'pages/manage/page/view',
]);
$app->getUrlManager()->addRules([ // add languages
'pages/manage/page/view/<id:\d+>' => 'pages/manage/page/view', $app->getI18n()->translations = ArrayHelper::merge($app->getI18n()->translations, [
]); 'pages' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@common/modules/pages/messages',
],
'page_public' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@common/modules/pages/messages',
],
]);
// add languages // add menu items
$app->getI18n()->translations = ArrayHelper::merge($app->getI18n()->translations, [ if (basename($app->getBasePath()) === 'backend') {
'pages' => [ $app->params['adminMenu'][] = [
'class' => 'yii\i18n\PhpMessageSource', 'label' => \Yii::t('pages', 'Pages'),
'basePath' => '@common/modules/pages/messages', 'icon' => 'file-o',
], 'url' => ['/pages/manage/page/index'],
'page_public' => [ 'visible' => \Yii::$app->user->can('admin') || \Yii::$app->user->can('PagesManagement')
'class' => 'yii\i18n\PhpMessageSource', ];
'basePath' => '@common/modules/pages/messages', }
], }
]);
// add menu items public static function getMenuItemCreator($menu_id): array
if (basename($app->getBasePath()) === 'backend') { {
$app->params['adminMenu'][] = [ $widgets = [];
'label' => \Yii::t( 'pages', 'Pages' ), $widgets[] = [
'icon' => 'file-o', 'id' => 'pages',
'url' => [ '/pages/manage/page/index' ], 'title' => \Yii::t('pages', 'Pages'),
'visible' => \Yii::$app->user->can( 'admin' ) || \Yii::$app->user->can( 'PagesManagement' ) 'content' => MenuItemCreatorWidget::widget([
]; 'menu_id' => $menu_id,
} ]),
} ];
public static function getMenuItemCreator($menu_id): array return $widgets;
{ }
$widgets = [];
$widgets[] = [
'id' => 'pages',
'title' => \Yii::t('pages', 'Pages'),
'content' => MenuItemCreatorWidget::widget([
'menu_id' => $menu_id,
]),
];
return $widgets;
}
} }

76
common/modules/pages/controllers/PageController.php

@ -7,53 +7,53 @@ use frontend\components\FrontendController;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\AccessControl; use yii\filters\AccessControl;
class PageController extends FrontendController class PageController extends FrontendController
{ {
private $pages; private $_pages;
public $layout = 'page'; public $layout = 'page';
public function __construct($id, $module, PageReadRepository $pages, $config = []) public function __construct($id, $module, PageReadRepository $pages, $config = [])
{ {
parent::__construct($id, $module, $config); parent::__construct($id, $module, $config);
$this->pages = $pages; $this->_pages = $pages;
} }
public function behaviors(): array public function behaviors(): array
{ {
return [ return [
'access' => [ 'access' => [
'class' => AccessControl::class, 'class' => AccessControl::class,
'rules' => [ 'rules' => [
[ [
'actions' => ['view'], 'actions' => ['view'],
'allow' => true, 'allow' => true,
'roles' => ['Pages'], 'roles' => ['Pages'],
], ],
[ [
'actions' => ['preview'], 'actions' => ['preview'],
'allow' => true, 'allow' => true,
'roles' => ['PagesManagement'], 'roles' => ['PagesManagement'],
], ],
[ // all the action are accessible to admin [ // all the action are accessible to admin
'allow' => true, 'allow' => true,
'roles' => ['admin'], 'roles' => ['admin'],
], ],
], ],
], ],
]; ];
} }
/** /**
* @param $id * @param $id
*
* @return mixed * @return mixed
* @throws NotFoundHttpException * @throws NotFoundHttpException
* @internal param string $slug * @internal param string $slug
*/ */
public function actionView($id) public function actionView($id)
{ {
if (!$page = $this->pages->find($id)) { if (!$page = $this->_pages->find($id)) {
throw new NotFoundHttpException('The requested page does not exist.'); throw new NotFoundHttpException('The requested page does not exist.');
} }
@ -62,14 +62,14 @@ class PageController extends FrontendController
]); ]);
} }
public function actionPreview($id, $language = '') public function actionPreview($id, $language = '')
{ {
if (!$page = $this->pages->findPreview($id, $language)) { if (!$page = $this->_pages->findPreview($id, $language)) {
throw new NotFoundHttpException('The requested page does not exist.'); throw new NotFoundHttpException('The requested page does not exist.');
} }
return $this->render('view', [ return $this->render('view', [
'page' => $page, 'page' => $page,
]); ]);
} }
} }

90
common/modules/pages/entities/Page.php

@ -27,8 +27,8 @@ use Yii;
* @method ActiveRecord findTranslation(string $language) * @method ActiveRecord findTranslation(string $language)
* @method void saveTranslations($translations) * @method void saveTranslations($translations)
* *
* @property ActiveRecord[] translations * @property ActiveRecord[] $translations
* @property ActiveRecord[] translation * @property ActiveRecord[] $translation
* *
* @property Page $parent * @property Page $parent
* @property Page[] $parents * @property Page[] $parents
@ -39,19 +39,20 @@ use Yii;
*/ */
class Page extends ActiveRecord class Page extends ActiveRecord
{ {
const TYPE_PUBLIC = 0; const TYPE_PUBLIC = 0;
const TYPE_REVISION = 1; const TYPE_REVISION = 1;
const TYPE_PREVIEW = 2; const TYPE_PREVIEW = 2;
public $_form; public $_form;
public static function create($form, $slug, $type = Page::TYPE_PUBLIC): self public static function create($form, $slug, $type = Page::TYPE_PUBLIC): self
{ {
$page = new static(); $page = new static();
$page->slug = $slug; $page->slug = $slug;
$page->type = $type; $page->type = $type;
$page->_form = $form; $page->_form = $form;
return $page; return $page;
} }
@ -65,7 +66,7 @@ class Page extends ActiveRecord
public function getSeoTitle(): string public function getSeoTitle(): string
{ {
return $this->translation->meta_title ?: $this->translation->title; return $this->translation->meta_title ?: $this->translation->title;
} }
public static function tableName(): string public static function tableName(): string
@ -76,30 +77,30 @@ class Page extends ActiveRecord
public function behaviors(): array public function behaviors(): array
{ {
return [ return [
[ [
'class' => NestedSetsBehavior::class, 'class' => NestedSetsBehavior::class,
'treeAttribute' => 'tree', 'treeAttribute' => 'tree',
], ],
TimestampBehavior::class, TimestampBehavior::class,
WidgetContentBehavior::class, WidgetContentBehavior::class,
[ [
'class' => LanguageBehavior::class, 'class' => LanguageBehavior::class,
'virtualClassName' => 'PagesVirtualTranslate', 'virtualClassName' => 'PagesVirtualTranslate',
'translatedLanguages' => \Yii::$app->params['translatedLanguages'], 'translatedLanguages' => \Yii::$app->params['translatedLanguages'],
'relativeField' => 'page_id', 'relativeField' => 'page_id',
'tableName' => "{{%pages_lng}}", 'tableName' => '{{%pages_lng}}',
'attributes' => ['title', 'content', 'meta_title', 'meta_description', 'meta_keywords'], 'attributes' => ['title', 'content', 'meta_title', 'meta_description', 'meta_keywords'],
'defaultLanguage' => \Yii::$app->params['defaultLanguage'], 'defaultLanguage' => \Yii::$app->params['defaultLanguage'],
//'defaultLanguage' => basename(Yii::$app->getBasePath()) === 'backend' ? Yii::$app->language : Yii::$app->params['defaultLanguage'], //'defaultLanguage' => basename(Yii::$app->getBasePath()) === 'backend' ? Yii::$app->language : Yii::$app->params['defaultLanguage'],
], ],
[ [
//'class' => SluggableBehavior::class, //'class' => SluggableBehavior::class,
'class' => SluggableRelationBehavior::class, 'class' => SluggableRelationBehavior::class,
'attribute' => 'title', 'attribute' => 'title',
'relation' => 'translation', 'relation' => 'translation',
//'ensureUnique' => true, //'ensureUnique' => true,
//'preserveNonEmptyValues' => true, //'preserveNonEmptyValues' => true,
], ],
]; ];
} }
@ -110,17 +111,18 @@ class Page extends ActiveRecord
]; ];
} }
public function attributeLabels() { public function attributeLabels()
return [ {
'title' => Yii::t('pages', 'Title'), return [
'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'),
]; 'content' => Yii::t('pages', 'Content'),
];
} }
public static function find(): PageQuery public static function find(): PageQuery
{ {
return new PageQuery(static::class); return new PageQuery(static::class);
} }
} }

84
common/modules/pages/urls/PageMainUrlRule.php

@ -14,8 +14,8 @@ use yii;
class PageMainUrlRule extends BaseObject implements UrlRuleInterface class PageMainUrlRule extends BaseObject implements UrlRuleInterface
{ {
//public $prefix = 'pages/page'; //public $prefix = 'pages/page';
public $prefix = ''; public $prefix = '';
private $repository; private $repository;
private $cache; private $cache;
@ -24,64 +24,70 @@ class PageMainUrlRule extends BaseObject implements UrlRuleInterface
{ {
parent::__construct($config); parent::__construct($config);
$this->repository = $repository; $this->repository = $repository;
$this->cache = $cache; $this->cache = $cache;
} }
public function parseRequest($manager, $request) public function parseRequest($manager, $request)
{ {
$uri = ltrim(LanguageHelper::processLangInUrl($request->pathInfo), '/'); $uri = ltrim(LanguageHelper::processLangInUrl($request->pathInfo), '/');
//if (preg_match('#^' . $this->prefix . '(.*[a-z])$#is', $request->pathInfo, $matches)) { //if (preg_match('#^' . $this->prefix . '(.*[a-z])$#is', $request->pathInfo, $matches)) {
//if (preg_match('#^' . $this->prefix . '([0-9a-z_\-]*)$#is', $request->pathInfo, $matches)) { //if (preg_match('#^' . $this->prefix . '([0-9a-z_\-]*)$#is', $request->pathInfo, $matches)) {
if (preg_match('#^' . $this->prefix . '([0-9a-z_\-]*)$#is', $uri, $matches)) { if (preg_match('#^' . $this->prefix . '([0-9a-z_\-]*)$#is', $uri, $matches)) {
$path = $matches['1']; $path = $matches['1'];
$result = $this->cache->getOrSet( [ 'page_main_route', 'path' => $path ], function () use ( $path ) { $result = $this->cache->getOrSet(['page_main_route', 'path' => $path], function () use ($path) {
if ( ! $post = $this->repository->findBySlug($this->getPathSlug( $path ) ) ) { if (!$post = $this->repository->findBySlug($this->getPathSlug($path))) {
return [ 'id' => null, 'path' => null ]; return ['id' => null, 'path' => null];
} }
return [ 'id' => $post->id, 'path' => $post->slug ];
}, null, new TagDependency(['tags' => ['pages']]) ); return ['id' => $post->id, 'path' => $post->slug];
}, null, new TagDependency(['tags' => ['pages']]));
if ( empty( $result['id'] ) ) {
return false; if (empty($result['id'])) {
} return false;
}
if ( $path != $result['path'] ) {
throw new UrlNormalizerRedirectException( [ 'pages/page/view', 'id' => $result['id'] ], 301 ); if ($path != $result['path']) {
} throw new UrlNormalizerRedirectException(['pages/page/view', 'id' => $result['id']], 301);
}
return ['pages/page/view', ['id' => $result['id']]];
} return ['pages/page/view', ['id' => $result['id']]];
return false; }
return false;
} }
public function createUrl($manager, $route, $params) public function createUrl($manager, $route, $params)
{ {
if ($route == 'pages/page/view') { if ($route == 'pages/page/view') {
if (empty($params['id'])) { if (empty($params['id'])) {
throw new InvalidArgumentException('Empty id.'); throw new InvalidArgumentException('Empty id.');
} }
$id = $params['id']; $id = $params['id'];
$url = $this->cache->getOrSet(['page_main_route', 'id' => $id], function () use ($id) { $url = $this->cache->getOrSet(['page_main_route', 'id' => $id], function () use ($id) {
if (!$page = $this->repository->find($id)) { if (!$page = $this->repository->find($id)) {
return null; return null;
} }
return $page->slug; return $page->slug;
}, null, new TagDependency(['tags' => ['pages']])); }, null, new TagDependency(['tags' => ['pages']]));
if (!$url) { if (!$url) {
return '#'; return '#';
//throw new InvalidArgumentException('Undefined id.'); //throw new InvalidArgumentException('Undefined id.');
} }
return LanguageHelper::addLangToUrl($url, isset($params['language']) ? $params['language'] : null);
return LanguageHelper::addLangToUrl($url, isset($params['language']) ? $params['language'] : null);
} }
return false; return false;
} }
private function getPathSlug($path): string private function getPathSlug($path): string
{ {
$chunks = explode('/', $path); $chunks = explode('/', $path);
return end($chunks);
} return end($chunks);
}
} }

41
frontend/components/FrontendController.php

@ -6,33 +6,32 @@
namespace frontend\components; namespace frontend\components;
use yii\web\Cookie;
use yii\base\Theme; use yii\base\Theme;
use yii\web\Controller; use yii\web\Controller;
use Yii; use Yii;
class FrontendController extends Controller class FrontendController extends Controller
{ {
public function init() { public function init()
parent::init(); {
parent::init();
// language // language
$languages = ['ru', 'en']; $languages = \Yii::$app->params['translatedLanguages'];
$language = Yii::$app->request->get('language'); $language = Yii::$app->request->get('language');
Yii::$app->language = $language && in_array($language, $languages) ? $language : Yii::$app->language; Yii::$app->language = $language && in_array($language, $languages) ? $language : Yii::$app->language;
// themes // themes
$theme = isset(Yii::$app->params['settings']['design']['theme']) ? Yii::$app->params['settings']['design']['theme'] : 'start'; $theme = isset(Yii::$app->params['settings']['design']['theme']) ? Yii::$app->params['settings']['design']['theme'] : 'start';
Yii::$app->view->theme = new Theme([ Yii::$app->view->theme = new Theme([
'basePath' => '@webroot/themes/' . $theme, 'basePath' => '@webroot/themes/' . $theme,
'baseUrl' => '@web/themes/' . $theme, 'baseUrl' => '@web/themes/' . $theme,
'pathMap' => [ 'pathMap' => [
'@common/modules' => '@webroot/themes/' . $theme . '/modules', '@common/modules' => '@webroot/themes/' . $theme . '/modules',
'@frontend/views' => '@webroot/themes/' . $theme, '@frontend/views' => '@webroot/themes/' . $theme,
'@frontend/widgets' => '@webroot/themes/' . $theme . '/widgets', '@frontend/widgets' => '@webroot/themes/' . $theme . '/widgets',
], ],
]); ]);
} }
} }

Loading…
Cancel
Save