Browse Source

Menu Management

Pages module
master
Egorka 6 years ago
parent
commit
bbdb0ba954
  1. 90
      backend/components/menu/widgets/views/_item.php
  2. 52
      backend/components/menu/widgets/views/menu.php
  3. 80
      backend/controllers/MenuController.php
  4. 2
      backend/messages/ru/main.php
  5. 12
      backend/messages/ru/menu.php
  6. 4
      backend/views/layouts/left.php
  7. 6
      backend/views/menu/menu.php
  8. 3
      common/modules/blog/BlogModule.php
  9. 21
      common/modules/blog/widgets/views/menu-item/creator.php
  10. 57
      common/modules/links/LinksModule.php
  11. 4
      common/modules/links/messages/ru/link.php
  12. 26
      common/modules/links/widgets/MenuItemCreatorWidget.php
  13. 40
      common/modules/links/widgets/views/menu-item/creator.php
  14. 78
      common/modules/pages/PagesModule.php
  15. 8
      common/modules/pages/controllers/PageController.php
  16. 32
      common/modules/pages/controllers/manage/PageController.php
  17. 2
      common/modules/pages/entities/Page.php
  18. 6
      common/modules/pages/forms/PageForm.php
  19. 4
      common/modules/pages/forms/PageSearch.php
  20. 1
      common/modules/pages/messages/ru/page.php
  21. 4
      common/modules/pages/repositories/PageRepository.php
  22. 4
      common/modules/pages/repositories/read/PageReadRepository.php
  23. 8
      common/modules/pages/services/PageManageService.php
  24. 89
      common/modules/pages/urls/PageMainUrlRule.php
  25. 4
      common/modules/pages/views/manage/page/_form.php
  26. 2
      common/modules/pages/views/manage/page/create.php
  27. 4
      common/modules/pages/views/manage/page/index.php
  28. 4
      common/modules/pages/views/manage/page/update.php
  29. 2
      common/modules/pages/views/manage/page/view.php
  30. 2
      common/modules/pages/views/page/view.php
  31. 29
      common/modules/pages/widgets/MenuItemCreatorWidget.php
  32. 95
      common/modules/pages/widgets/views/menu-item/creator.php
  33. 26
      core/entities/menu/MenuItem.php
  34. 22
      core/widgets/menu/MenuWidget.php
  35. 30
      core/widgets/menu/views/menu.php
  36. 12
      frontend/web/themes/start/layouts/main.php
  37. 28
      frontend/web/themes/start/modules/pages/views/layouts/page.php
  38. 32
      frontend/web/themes/start/modules/pages/views/page/view.php

90
backend/components/menu/widgets/views/_item.php

@ -4,6 +4,8 @@
* Date: 11.07.2018 * Date: 11.07.2018
*/ */
use yii\helpers\Html;
/** /**
* @var $this \yii\web\View * @var $this \yii\web\View
* @var $item array * @var $item array
@ -22,12 +24,96 @@ $menu_item = $item['item'];
<h4 class="panel-title"> <h4 class="panel-title">
<div class="dd-handle dd3-handle"> </div> <div class="dd-handle dd3-handle"> </div>
<a data-toggle="collapse" data-parent="#accordion" href="#collapse<?= $menu_item->id ?>"><?= $menu_item->name ?> <a data-toggle="collapse" data-parent="#accordion" href="#collapse<?= $menu_item->id ?>"><?= $menu_item->name ?>
<i class="fa fa-angle-down pull-right" aria-hidden="true"></i></a> <i class="fa fa-angle-down pull-right" aria-hidden="true"></i> <span style="font-size: 14px; color: #999" class="pull-right"><?= $menu_item->module ?></span></a>
</h4> </h4>
</div> </div>
<div id="collapse<?= $menu_item->id ?>" class="panel-collapse collapse"> <div id="collapse<?= $menu_item->id ?>" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
Content Panel
<div class="row" style="font-weight: normal">
<div class="col-md-6">
<?= Html::label(Yii::t('menu','Item Name'), 'item-name', [
'style' => 'color: #555555',
]) ?>
<?= Html::input('text', 'item-name', $menu_item->name, [
'id' => 'item-name-' . $menu_item->id,
'class' => 'form-control',
]) ?>
</div>
<div class="col-md-6">
<?= Html::label(Yii::t('menu','Item Title Attribute'), 'item-title-attr', [
'style' => 'color: #555555',
]) ?>
<?= Html::input('text', 'item-title-attr', $menu_item->title_attr, [
'id' => 'item-title-attr-' . $menu_item->id,
'class' => 'form-control',
]) ?>
</div>
</div>
<div class="row" style="font-weight: normal; margin-top: 5px;">
<div class="col-md-6">
<?= Html::label(Yii::t('menu','Style Attribute'), 'item-style', [
'style' => 'color: #555555',
]) ?>
<?= Html::input('text', 'item-style', $menu_item->style, [
'id' => 'item-style-' . $menu_item->id,
'class' => 'form-control',
]) ?>
</div>
<div class="col-md-6">
<?= Html::label(Yii::t('menu','CSS'), 'item-css', [
'style' => 'color: #555555',
]) ?>
<?= Html::input('text', 'item-css', $menu_item->css, [
'id' => 'item-css-' . $menu_item->id,
'class' => 'form-control',
]) ?>
</div>
</div>
<div class="row" style="font-weight: normal; margin-top: 5px;">
<?php if (!$menu_item->url_params): ?>
<div class="col-md-6">
<?= Html::label(Yii::t('menu','URL'), 'item-url', [
'style' => 'color: #555555',
]) ?>
<?= Html::input('text', 'item-url', $menu_item->url, [
'id' => 'item-url-' . $menu_item->id,
'class' => 'form-control',
]) ?>
</div>
<?php else: ?>
<?= Html::hiddenInput('item-url', $menu_item->url, [
'id' => 'item-url-' . $menu_item->id,
]) ?>
<?php endif; ?>
<div class="col-md-6">
<?= Html::label(Yii::t('menu','Target'), 'item-target', [
'style' => 'color: #555555',
]) ?>
<?= Html::dropDownList('item-target', $menu_item->target, [
'' => Yii::t('menu', 'Self Window'),
'_blank' => Yii::t('menu', 'Blank Window'),
], [
'id' => 'item-target-' . $menu_item->id,
'class' => 'form-control',
]) ?>
</div>
</div>
<hr>
<div class="pull-right">
<?= Html::a(Yii::t('buttons', 'Delete'), '#', [
'class' => 'item-delete-button btn btn-sm btn-danger',
'data-id' => $menu_item->id,
]) ?>
<?= Html::a(Yii::t('buttons', 'Save'), '#', [
'class' => 'item-save-button btn btn-sm btn-success',
'data-id' => $menu_item->id,
]) ?>
</div>
</div> </div>
</div> </div>
</div> </div>

52
backend/components/menu/widgets/views/menu.php

@ -27,6 +27,58 @@ function menu_generate($items) {
return $html . '</ol>'; return $html . '</ol>';
} }
$name_empty_error = Yii::t('menu', 'Name must be specified');
$item_save_url = Url::to(['menu/save-menu-item-data']);
$item_delete_url = Url::to(['menu/delete-menu-item']);
$confirm_delete_message = Yii::t('buttons', 'Are you sure you want to delete this item?');
$current_url = Url::to(['menu/index', 'id' => $menu->id]);
$js = <<<JS
$(".item-save-button").on('click', function(e) {
e.preventDefault();
var id = $(this).data('id');
var name = $("#item-name-" + id).val();
var title = $("#item-title-attr-" + id).val();
var style = $("#item-style-" + id).val();
var css = $("#item-css-" + id).val();
var url = $("#item-url-" + id).val();
var target = $("#item-target-" + id).val();
if (name) {
$.ajax({
method: "POST",
url: "{$item_save_url}",
data: { name: name, title: title, style: style, css: css, url: url, target: target, id: id }
})
.done(function( data ) {
if (data.result === 'success') {
document.location.href = '{$current_url}';
}
});
}
else {
alert('{$name_empty_error}');
}
});
$(".item-delete-button").on('click', function(e) {
e.preventDefault();
if (confirm('{$confirm_delete_message}')) {
var id = $(this).data('id');
$.ajax({
method: "POST",
url: "{$item_delete_url}",
data: { id: id }
})
.done(function( data ) {
if (data.result === 'success') {
document.location.href = '{$current_url}';
}
});
}
});
JS;
$this->registerJs($js, $this::POS_READY);
$url = Url::to(['/menu/save-menu-items']); $url = Url::to(['/menu/save-menu-items']);
$redirect = Url::to(['menu/index', 'id' => $menu->id]); $redirect = Url::to(['menu/index', 'id' => $menu->id]);
?> ?>

80
backend/controllers/MenuController.php

@ -6,8 +6,6 @@
namespace backend\controllers; namespace backend\controllers;
use common\modules\blog\BlogModule;
use core\entities\menu\Menu; use core\entities\menu\Menu;
use core\entities\menu\MenuItem; use core\entities\menu\MenuItem;
use core\entities\ModuleRecord; use core\entities\ModuleRecord;
@ -42,7 +40,7 @@ class MenuController extends Controller
'class' => AccessControl::class, 'class' => AccessControl::class,
'rules' => [ 'rules' => [
[ [
'actions' => ['create', 'update', 'delete', 'index', 'save-menu-items'], 'actions' => ['create', 'update', 'delete', 'index', 'save-menu-items', 'save-menu-item-data', 'delete-menu-item'],
'allow' => true, 'allow' => true,
'roles' => ['MenuManagement'], 'roles' => ['MenuManagement'],
], ],
@ -56,6 +54,7 @@ class MenuController extends Controller
'class' => VerbFilter::class, 'class' => VerbFilter::class,
'actions' => [ 'actions' => [
'delete' => ['POST'], 'delete' => ['POST'],
'delete-menu-item' => ['POST'],
], ],
], ],
]; ];
@ -139,6 +138,72 @@ class MenuController extends Controller
return $this->redirect(['index']); return $this->redirect(['index']);
} }
public function actionDeleteMenuItem()
{
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
if (Yii::$app->request->isAjax) {
try {
$id = Yii::$app->request->post('id');
$item = $this->findItemModel($id);
//$this->deleteItem($item);
$item->delete();
Yii::$app->session->setFlash('success', Yii::t('menu', 'Menu Item Deleted'));
return [ 'result' => 'success' ];
}
catch (\RuntimeException $e) {
return [ 'result' => 'error', 'message' => $e->getMessage() ];
}
}
return ['result' => 'error', 'message' => 'Request error'];
}
//private function deleteItem(MenuItem $item): void
//{
/*if ($item->hasChildren()) {
$children = $item->children;
foreach ($children as $child) {
$this->deleteItem($child);
}
}*/
//$item->delete();
//}
public function actionSaveMenuItemData()
{
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
if (Yii::$app->request->isAjax) {
try {
$id = Yii::$app->request->post('id');
$name = Yii::$app->request->post('name');
$title = Yii::$app->request->post('title');
$style = Yii::$app->request->post('style');
$css = Yii::$app->request->post('css');
$url = Yii::$app->request->post('url');
$target = Yii::$app->request->post('target');
$item = $this->findItemModel($id);
$item->name = $name;
$item->title_attr = $title;
$item->style = $style;
$item->css = $css;
$item->url = $url;
$item->target = $target;
$item->save();
Yii::$app->session->setFlash('success', Yii::t('menu', 'Menu Item Saved'));
return [ 'result' => 'success' ];
}
catch (\RuntimeException $e) {
return [ 'result' => 'error', 'message' => $e->getMessage() ];
}
}
return ['result' => 'error', 'message' => 'Request error'];
}
public function actionSaveMenuItems() public function actionSaveMenuItems()
{ {
$json = Yii::$app->request->post('json'); $json = Yii::$app->request->post('json');
@ -151,6 +216,7 @@ class MenuController extends Controller
$order[$item[1]] = isset($order[$item[1]]) ? $order[$item[1]]+1 : 0; $order[$item[1]] = isset($order[$item[1]]) ? $order[$item[1]]+1 : 0;
$this->menu_item_service->setPosition($item, $order[$item[1]]); $this->menu_item_service->setPosition($item, $order[$item[1]]);
} }
Yii::$app->session->setFlash('success', Yii::t('menu', 'Menu Saved'));
return [ 'result' => 'success' ]; return [ 'result' => 'success' ];
} }
catch (\RuntimeException $e) { catch (\RuntimeException $e) {
@ -192,4 +258,12 @@ class MenuController extends Controller
} }
throw new NotFoundHttpException('The requested menu does not exist.'); throw new NotFoundHttpException('The requested menu does not exist.');
} }
protected function findItemModel($id): MenuItem
{
if (($model = MenuItem::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested menu item does not exist.');
}
} }

2
backend/messages/ru/main.php

@ -28,4 +28,6 @@ return [
'Search results' => 'Поиск', 'Search results' => 'Поиск',
'Search...' => 'Поиск...', 'Search...' => 'Поиск...',
'Name' => 'Название', 'Name' => 'Название',
'Title attribute' => 'Атрибут тега Title',
'Url' => 'Ссылка',
]; ];

12
backend/messages/ru/menu.php

@ -9,4 +9,16 @@ return [
'Current Menu' => 'Текущее меню', 'Current Menu' => 'Текущее меню',
'Available Blocks' => 'Доступные блоки', 'Available Blocks' => 'Доступные блоки',
'Menu Items' => 'Элементы меню', 'Menu Items' => 'Элементы меню',
'Item Name' => 'Название',
'Item Title Attribute' => 'Атрибут Title',
'Style Attribute' => 'Атрибут Style',
'CSS' => 'Класс CSS',
'Self Window' => 'Текущее окно',
'Blank Window' => 'Новое окно',
'Target' => 'Цель',
'URL' => 'Ссылка',
'Name must be specified' => 'Укажите название пункта меню',
'Menu Item Saved' => 'Пункт меню сохранен',
'Menu Item Deleted' => 'Пункт меню удален',
'Menu Saved' => 'Меню сохранено',
]; ];

4
backend/views/layouts/left.php

@ -83,12 +83,12 @@ $model = new SearchForm();
'visible' => \Yii::$app->user->can('admin') || \Yii::$app->user->can('MenuManagement'), 'visible' => \Yii::$app->user->can('admin') || \Yii::$app->user->can('MenuManagement'),
], ],
[ /*[
'label' => Yii::t('page', 'Pages'), 'label' => Yii::t('page', 'Pages'),
'icon' => 'file-o', 'url' => ['/page/index'], 'icon' => 'file-o', 'url' => ['/page/index'],
'active' => $this->context->id == 'page', 'active' => $this->context->id == 'page',
'visible' => \Yii::$app->user->can('admin') || \Yii::$app->user->can('PagesManagement'), 'visible' => \Yii::$app->user->can('admin') || \Yii::$app->user->can('PagesManagement'),
], ],*/
['label' => Yii::t('post', 'Posts'), 'icon' => 'newspaper-o', 'items' => array_merge( ['label' => Yii::t('post', 'Posts'), 'icon' => 'newspaper-o', 'items' => array_merge(
array_map(function(\core\entities\post\PostType $type) { array_map(function(\core\entities\post\PostType $type) {

6
backend/views/menu/menu.php

@ -75,13 +75,13 @@ $this->params['breadcrumbs'][] = $this->title;
<?php foreach ($creator as $item): ?> <?php foreach ($creator as $item): ?>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading" style="padding-left: 0">
<h4 class="panel-title"> <h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne"><?= $item['title'] ?> <a data-toggle="collapse" data-parent="#accordion" href="#collapse<?= $item['id'] ?>"><?= $item['title'] ?>
<i class="fa fa-angle-down pull-right" aria-hidden="true"></i></a> <i class="fa fa-angle-down pull-right" aria-hidden="true"></i></a>
</h4> </h4>
</div> </div>
<div id="collapseOne" class="panel-collapse collapse"> <div id="collapse<?= $item['id'] ?>" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
<?= $item['content'] ?> <?= $item['content'] ?>
</div> </div>

3
common/modules/blog/BlogModule.php

@ -1,11 +1,11 @@
<?php <?php
namespace common\modules\blog; namespace common\modules\blog;
use common\modules\blog\widgets\MenuItemCreatorWidget; use common\modules\blog\widgets\MenuItemCreatorWidget;
use core\components\modules\ModuleInterface; use core\components\modules\ModuleInterface;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
/** /**
* blog module definition class * blog module definition class
*/ */
@ -103,6 +103,7 @@ class BlogModule extends \yii\base\Module implements ModuleInterface
{ {
$widgets = []; $widgets = [];
$widgets[] = [ $widgets[] = [
'id' => 'blog',
'title' => \Yii::t('blog', 'Blog'), 'title' => \Yii::t('blog', 'Blog'),
'content' => MenuItemCreatorWidget::widget([ 'content' => MenuItemCreatorWidget::widget([
'menu_id' => $menu_id, 'menu_id' => $menu_id,

21
common/modules/blog/widgets/views/menu-item/creator.php

@ -14,26 +14,35 @@ use yii\helpers\Html;
use yii\web\JsExpression; use yii\web\JsExpression;
use yii\helpers\Url; use yii\helpers\Url;
$block_name = Yii::t('blog', 'Blog');
$block_title_attr = Yii::t('blog', 'Blog');
$js = <<<JS $js = <<<JS
function selectBlogPostOn() { function selectBlogPostOn() {
$("#post_select").removeAttr('disabled'); $("#post_select").removeAttr('disabled');
updateUrl('post') updateBlogUrl('post');
} }
function selectBlogPostOff() { function selectBlogPostOff() {
$("#post_select").attr('disabled', 'disabled'); $("#post_select").attr('disabled', 'disabled');
updateUrl('blog') updateBlogUrl('blog');
} }
function updateUrl(type) { function updateBlogUrl(type) {
if (type === 'blog') { if (type === 'blog') {
$("#blog_menu_item_url").val('/blog/post/index'); $("#blog_menu_item_url").val('/blog/post/index');
$("#blog_menu_item_url_params").val(''); $("#blog_menu_item_url_params").val('');
$("#blog_menu_item_name").val('{$block_name}');
$("#blog_menu_item_title_attr").val('$block_title_attr');
} }
else { else {
var selected_post = $("#post_select").val(); var select = $("#post_select");
var data = select.select2('data');
var selected_post = select.val();
$("#blog_menu_item_url").val('/blog/post/post/'); $("#blog_menu_item_url").val('/blog/post/post/');
$("#blog_menu_item_url_params").val('{"id":'+selected_post+'}'); $("#blog_menu_item_url_params").val('{"id":'+selected_post+'}');
$("#blog_menu_item_name").val(data[0].text);
$("#blog_menu_item_title_attr").val(data[0].text);
} }
} }
JS; JS;
@ -66,7 +75,7 @@ $fetchUrl = Url::to( [ '/blog/manage/post/post-search' ] );
'options' => [ 'options' => [
'placeholder' => Yii::t('blog', 'Select post...'), 'placeholder' => Yii::t('blog', 'Select post...'),
'id' => 'post_select', 'id' => 'post_select',
'onchange' => new JsExpression("updateUrl('post')"), 'onchange' => new JsExpression("updateBlogUrl('post')"),
], ],
'pluginOptions' => [ 'pluginOptions' => [
'disabled' => true, 'disabled' => true,
@ -86,9 +95,11 @@ $fetchUrl = Url::to( [ '/blog/manage/post/post-search' ] );
<?php $form = ActiveForm::begin(); ?> <?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->hiddenInput([ <?= $form->field($model, 'name')->hiddenInput([
'id' => 'blog_menu_item_name',
])->label(false) ?> ])->label(false) ?>
<?= $form->field($model, 'title_attr')->hiddenInput([ <?= $form->field($model, 'title_attr')->hiddenInput([
'id' => 'blog_menu_item_title_attr',
])->label(false) ?> ])->label(false) ?>
<?= $form->field($model, 'module')->hiddenInput([ <?= $form->field($model, 'module')->hiddenInput([

57
common/modules/links/LinksModule.php

@ -0,0 +1,57 @@
<?php
namespace common\modules\links;
use common\modules\links\widgets\MenuItemCreatorWidget;
use core\components\modules\ModuleInterface;
use yii\helpers\ArrayHelper;
/**
* blog module definition class
*/
class LinksModule extends \yii\base\Module implements ModuleInterface
{
/**
* @inheritdoc
*/
public $controllerNamespace = 'common\modules\links\controllers';
/**
* @inheritdoc
*/
public function init()
{
parent::init();
// custom initialization code goes here
}
public function bootstrap($app)
{
// add languages
$app->getI18n()->translations = ArrayHelper::merge($app->getI18n()->translations, [
'link' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@common/modules/links/messages',
],
'link_public' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@common/modules/links/messages',
],
]);
}
public static function getMenuItemCreator($menu_id): array
{
$widgets = [];
$widgets[] = [
'id' => 'links',
'title' => \Yii::t('link', 'Links'),
'content' => MenuItemCreatorWidget::widget([
'menu_id' => $menu_id,
]),
];
return $widgets;
}
}

4
common/modules/links/messages/ru/link.php

@ -0,0 +1,4 @@
<?php
return [
'Links' => 'Ссылки',
];

26
common/modules/links/widgets/MenuItemCreatorWidget.php

@ -0,0 +1,26 @@
<?php
/**
* Created by Error202
* Date: 10.07.2018
*/
namespace common\modules\links\widgets;
use core\forms\menu\MenuItemForm;
use yii\base\Widget;
class MenuItemCreatorWidget extends Widget
{
public $menu_id;
public function run()
{
$form = new MenuItemForm();
$form->module = \Yii::t('link', 'Links');
$form->menu_id = $this->menu_id;
return $this->render('menu-item/creator', [
'model' => $form,
]);
}
}

40
common/modules/links/widgets/views/menu-item/creator.php

@ -0,0 +1,40 @@
<?php
/**
* Created by Error202
* Date: 10.07.2018
*/
/**
* @var $this \yii\web\View
* @var $model \core\forms\menu\MenuItemForm
*/
use yii\widgets\ActiveForm;
use yii\helpers\Html;
?>
<div class="menu_item_widget">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->input('text') ?>
<?= $form->field($model, 'title_attr')->input('text') ?>
<?= $form->field($model, 'module')->hiddenInput()->label(false) ?>
<?= $form->field($model, 'menu_id')->hiddenInput()->label(false) ?>
<?= $form->field($model, 'url')->input('text') ?>
<?= $form->field($model, 'url_params')->hiddenInput()->label(false) ?>
<div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Add to menu'), [
'class' => 'btn btn-info btn-sm pull-right'
]) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

78
common/modules/pages/PagesModule.php

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

8
frontend/controllers/PageController.php → common/modules/pages/controllers/PageController.php

@ -1,8 +1,8 @@
<?php <?php
namespace frontend\controllers; namespace common\modules\pages\controllers;
use core\repositories\page\read\PageReadRepository; use common\modules\pages\repositories\read\PageReadRepository;
use frontend\components\FrontendController; use frontend\components\FrontendController;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\AccessControl; use yii\filters\AccessControl;
@ -12,6 +12,8 @@ class PageController extends FrontendController
{ {
private $pages; private $pages;
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);
@ -22,7 +24,7 @@ class PageController extends FrontendController
{ {
return [ return [
'access' => [ 'access' => [
'class' => AccessControl::className(), 'class' => AccessControl::class,
'rules' => [ 'rules' => [
[ [
'actions' => ['view'], 'actions' => ['view'],

32
backend/controllers/PageController.php → common/modules/pages/controllers/manage/PageController.php

@ -1,16 +1,17 @@
<?php <?php
namespace backend\controllers; namespace common\modules\pages\controllers\manage;
use core\forms\PageForm; use common\modules\pages\forms\PageForm;
use core\services\PageManageService; use common\modules\pages\services\PageManageService;
use Yii; use common\modules\pages\entities\Page;
use core\entities\Page; use common\modules\pages\forms\PageSearch;
use backend\forms\PageSearch;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use Yii;
use yii\web\Response;
class PageController extends Controller class PageController extends Controller
{ {
@ -156,6 +157,25 @@ class PageController extends Controller
return $this->redirect(['index']); return $this->redirect(['index']);
} }
public function actionPageSearch($q = null, $id = null)
{
\Yii::$app->response->format = Response::FORMAT_JSON;
$out = ['results' => ['id' => '', 'text' => '']];
if (!is_null($q)) {
$data = Page::find()->select('id, title as text')->andWhere(['like', 'title', $q])->limit(20)->asArray()->all();
$out['results'] = array_values($data);
}
elseif ($id > 0) {
$tag_name = Page::findOne($id)->title;
$out['results'] = ['id' => $tag_name, 'text' => $tag_name];
}
else {
$data = Page::find()->select('id, title as text')->orderBy(['id' => SORT_DESC])->limit(20)->asArray()->all();
$out['results'] = array_values($data);
}
return $out;
}
/** /**
* @param integer $id * @param integer $id
* @return Page the loaded model * @return Page the loaded model

2
core/entities/Page.php → common/modules/pages/entities/Page.php

@ -1,6 +1,6 @@
<?php <?php
namespace core\entities; namespace common\modules\pages\entities;
use paulzi\nestedsets\NestedSetsBehavior; use paulzi\nestedsets\NestedSetsBehavior;
use core\behaviors\MetaBehavior; use core\behaviors\MetaBehavior;

6
core/forms/PageForm.php → common/modules/pages/forms/PageForm.php

@ -1,8 +1,10 @@
<?php <?php
namespace core\forms; namespace common\modules\pages\forms;
use core\entities\Page; use core\forms\CompositeForm;
use core\forms\MetaForm;
use common\modules\pages\entities\Page;
use core\validators\SlugValidator; use core\validators\SlugValidator;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use Yii; use Yii;

4
backend/forms/PageSearch.php → common/modules/pages/forms/PageSearch.php

@ -1,10 +1,10 @@
<?php <?php
namespace backend\forms; namespace common\modules\pages\forms;
use yii\base\Model; use yii\base\Model;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use core\entities\Page; use common\modules\pages\entities\Page;
class PageSearch extends Model class PageSearch extends Model
{ {

1
backend/messages/ru/page.php → common/modules/pages/messages/ru/page.php

@ -10,4 +10,5 @@ return [
'ID' => '№', 'ID' => '№',
'Parent Page' => 'Родительская страница', 'Parent Page' => 'Родительская страница',
'Update Page: {name}' => 'Редактирование страницы: {name}', 'Update Page: {name}' => 'Редактирование страницы: {name}',
'Select page...' => 'Укажите страницу',
]; ];

4
core/repositories/page/PageRepository.php → common/modules/pages/repositories/PageRepository.php

@ -1,8 +1,8 @@
<?php <?php
namespace core\repositories\page; namespace common\modules\pages\repositories;
use core\entities\Page; use common\modules\pages\entities\Page;
use core\repositories\NotFoundException; use core\repositories\NotFoundException;
class PageRepository class PageRepository

4
core/repositories/page/read/PageReadRepository.php → common/modules/pages/repositories/read/PageReadRepository.php

@ -1,8 +1,8 @@
<?php <?php
namespace core\repositories\page\read; namespace common\modules\pages\repositories\read;
use core\entities\Page; use common\modules\pages\entities\Page;
class PageReadRepository class PageReadRepository
{ {

8
core/services/PageManageService.php → common/modules/pages/services/PageManageService.php

@ -1,11 +1,11 @@
<?php <?php
namespace core\services; namespace common\modules\pages\services;
use core\entities\Meta; use core\entities\Meta;
use core\entities\Page; use common\modules\pages\entities\Page;
use core\forms\PageForm; use common\modules\pages\forms\PageForm;
use core\repositories\page\PageRepository; use common\modules\pages\repositories\PageRepository;
class PageManageService class PageManageService
{ {

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

@ -0,0 +1,89 @@
<?php
namespace common\modules\pages\urls;
use common\modules\pages\repositories\read\PageReadRepository;
use yii\base\BaseObject;
use yii\caching\Cache;
use yii\caching\TagDependency;
use yii\web\UrlNormalizerRedirectException;
use yii\web\UrlRuleInterface;
use InvalidArgumentException;
class PageMainUrlRule extends BaseObject implements UrlRuleInterface
{
//public $prefix = 'pages/page';
public $prefix = '';
private $repository;
private $cache;
public function __construct(PageReadRepository $repository, Cache $cache, $config = [])
{
parent::__construct($config);
$this->repository = $repository;
$this->cache = $cache;
}
public function parseRequest($manager, $request)
{
if (preg_match('#^' . $this->prefix . '(.*[a-z])$#is', $request->pathInfo, $matches)) {
$path = $matches['1'];
$result = $this->cache->getOrSet( [ 'page_main_route', 'path' => $path ], function () use ( $path ) {
if ( ! $post = $this->repository->findBySlug($this->getPathSlug( $path ) ) ) {
return [ 'id' => null, 'path' => null ];
}
return [ 'id' => $post->id, 'path' => $post->slug ];
}, null, new TagDependency(['tags' => ['pages']]) );
if ( empty( $result['id'] ) ) {
return false;
}
if ( $path != $result['path'] ) {
throw new UrlNormalizerRedirectException( [ 'pages/page/view', 'id' => $result['id'] ], 301 );
}
return ['pages/page/view', ['id' => $result['id']]];
}
return false;
}
public function createUrl($manager, $route, $params)
{
if ($route == 'pages/page/view') {
if (empty($params['id'])) {
throw new InvalidArgumentException('Empty id.');
}
$id = $params['id'];
$url = $this->cache->getOrSet(['page_main_route', 'id' => $id], function () use ($id) {
if (!$page = $this->repository->find($id)) {
return null;
}
return $page->slug;
}, null, new TagDependency(['tags' => ['pages']]));
if (!$url) {
return '#';
//throw new InvalidArgumentException('Undefined id.');
}
$url = $this->prefix . '/' . $url;
unset($params['id']);
if (!empty($params) && ($query = http_build_query($params)) !== '') {
$url .= '?' . $query;
}
return $url;
}
return false;
}
private function getPathSlug($path): string
{
$chunks = explode('/', $path);
return end($chunks);
}
}

4
backend/views/page/_form.php → common/modules/pages/views/manage/page/_form.php

@ -5,7 +5,7 @@ use yii\helpers\Html;
use yii\widgets\ActiveForm; use yii\widgets\ActiveForm;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $model core\forms\PageForm */ /* @var $model \common\modules\pages\forms\PageForm */
/* @var $form yii\widgets\ActiveForm */ /* @var $form yii\widgets\ActiveForm */
?> ?>
@ -19,7 +19,7 @@ use yii\widgets\ActiveForm;
<?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?> <?= $form->field($model, 'parentId')->dropDownList($model->parentsList()) ?>
<?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'title')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?> <?= $form->field($model, 'slug')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'content')->widget(CKEditor::className()) ?> <?= $form->field($model, 'content')->widget(CKEditor::class) ?>
</div> </div>
</div> </div>

2
backend/views/page/create.php → common/modules/pages/views/manage/page/create.php

@ -1,7 +1,7 @@
<?php <?php
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $model core\forms\PageForm */ /* @var $model \common\modules\pages\forms\PageForm */
$this->title = Yii::t('page', 'Create Page'); $this->title = Yii::t('page', 'Create Page');
$this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']];

4
backend/views/page/index.php → common/modules/pages/views/manage/page/index.php

@ -1,12 +1,12 @@
<?php <?php
use core\entities\Page; use common\modules\pages\entities\Page;
use yii\grid\ActionColumn; use yii\grid\ActionColumn;
use yii\helpers\Html; use yii\helpers\Html;
use yii\grid\GridView; use yii\grid\GridView;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $searchModel backend\forms\PageSearch */ /* @var $searchModel \common\modules\pages\forms\PageSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */ /* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = Yii::t('page', 'Pages'); $this->title = Yii::t('page', 'Pages');

4
backend/views/page/update.php → common/modules/pages/views/manage/page/update.php

@ -1,8 +1,8 @@
<?php <?php
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $page core\entities\Page */ /* @var $page \common\modules\pages\entities\Page */
/* @var $model core\forms\PageForm */ /* @var $model \common\modules\pages\forms\PageForm */
$this->title = Yii::t('page', 'Update Page: {name}', ['name' => $page->title]); $this->title = Yii::t('page', 'Update Page: {name}', ['name' => $page->title]);
$this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']];

2
backend/views/page/view.php → common/modules/pages/views/manage/page/view.php

@ -4,7 +4,7 @@ use yii\helpers\Html;
use yii\widgets\DetailView; use yii\widgets\DetailView;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $page core\entities\Page */ /* @var $page \common\modules\pages\entities\Page */
$this->title = $page->title; $this->title = $page->title;
$this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']]; $this->params['breadcrumbs'][] = ['label' => Yii::t('page', 'Pages'), 'url' => ['index']];

2
frontend/views/page/view.php → common/modules/pages/views/page/view.php

@ -3,7 +3,7 @@
use yii\helpers\Html; use yii\helpers\Html;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $page \core\entities\Page */ /* @var $page \common\modules\pages\entities\Page */
$this->title = $page->getSeoTitle(); $this->title = $page->getSeoTitle();

29
common/modules/pages/widgets/MenuItemCreatorWidget.php

@ -0,0 +1,29 @@
<?php
/**
* Created by Error202
* Date: 10.07.2018
*/
namespace common\modules\pages\widgets;
use core\forms\menu\MenuItemForm;
use yii\base\Widget;
class MenuItemCreatorWidget extends Widget
{
public $menu_id;
public function run()
{
$form = new MenuItemForm();
$form->module = \Yii::t('page', 'Pages');
$form->name = \Yii::t('page', 'Pages');
$form->title_attr = \Yii::t('page', 'Pages');
$form->menu_id = $this->menu_id;
$form->url = '/pages/page/index';
return $this->render('menu-item/creator', [
'model' => $form,
]);
}
}

95
common/modules/pages/widgets/views/menu-item/creator.php

@ -0,0 +1,95 @@
<?php
/**
* Created by Error202
* Date: 10.07.2018
*/
/**
* @var $this \yii\web\View
* @var $model \core\forms\menu\MenuItemForm
*/
use yii\widgets\ActiveForm;
use yii\helpers\Html;
use yii\web\JsExpression;
use yii\helpers\Url;
$block_name = Yii::t('page', 'Pages');
$block_title_attr = Yii::t('page', 'Pages');
$js = <<<JS
function updatePagesUrl() {
var select = $("#page_select");
var data = select.select2('data');
var selected_post = select.val();
$("#page_menu_item_url").val('/pages/page/view/');
$("#page_menu_item_url_params").val('{"id":'+selected_post+'}');
$("#page_menu_item_name").val(data[0].text);
$("#page_menu_item_title_attr").val(data[0].text);
}
JS;
$this->registerJs($js, $this::POS_HEAD);
$fetchUrl = Url::to( [ '/pages/manage/page/page-search' ] );
?>
<div class="menu_item_widget">
<div class="form-group">
<div>
<?= \kartik\widgets\Select2::widget([
'name' => 'page_select',
'value' => '',
'options' => [
'placeholder' => Yii::t('page', 'Select page...'),
'id' => 'page_select',
'onchange' => new JsExpression("updatePagesUrl()"),
],
'pluginOptions' => [
'ajax' => [
'url' => $fetchUrl,
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(tag) { return tag.text; }'),
'templateSelection' => new JsExpression('function (tag) { return tag.text; }'),
],
]) ?>
</div>
</div>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->hiddenInput([
'id' => 'page_menu_item_name',
])->label(false) ?>
<?= $form->field($model, 'title_attr')->hiddenInput([
'id' => 'page_menu_item_title_attr',
])->label(false) ?>
<?= $form->field($model, 'module')->hiddenInput([
])->label(false) ?>
<?= $form->field($model, 'menu_id')->hiddenInput([
])->label(false) ?>
<?= $form->field($model, 'url')->hiddenInput([
'id' => 'page_menu_item_url',
])->label(false) ?>
<?= $form->field($model, 'url_params')->hiddenInput([
'value' => '',
'id' => 'page_menu_item_url_params',
])->label(false) ?>
<div class="form-group">
<?= Html::submitButton(Yii::t('buttons', 'Add to menu'), [
'class' => 'btn btn-info btn-sm pull-right'
]) ?>
</div>
<?php ActiveForm::end(); ?>
</div>

26
core/entities/menu/MenuItem.php

@ -6,8 +6,9 @@
namespace core\entities\menu; namespace core\entities\menu;
use paulzi\sortable\SortableBehavior;
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
use yii\helpers\Json;
use yii\helpers\Url;
/** /**
* Class MenuItem * Class MenuItem
@ -91,11 +92,34 @@ class MenuItem extends ActiveRecord
return false; return false;
} }
public function beforeDelete(){
foreach($this->children as $child) {
$child->delete();
}
return parent::beforeDelete();
}
public function getUrl(): string
{
$params = $this->url_params ? Json::decode($this->url_params, true) : [];
return Url::to(array_merge([$this->url], $params));
}
public function isActive(): bool
{
return \Yii::$app->request->getUrl() == $this->getUrl();
}
public function getChildren() public function getChildren()
{ {
return $this->hasMany(MenuItem::class, ['parent_id' => 'id'])->orderBy(['sort' => SORT_ASC]); return $this->hasMany(MenuItem::class, ['parent_id' => 'id'])->orderBy(['sort' => SORT_ASC]);
} }
public function hasChildren(): bool
{
return $this->hasMany(MenuItem::class, ['parent_id' => 'id'])->orderBy(['sort' => SORT_ASC])->count() > 0 ? true : false;
}
public function getParent() public function getParent()
{ {
return $this->hasOne(MenuItem::class, ['id' => 'parent_id']); return $this->hasOne(MenuItem::class, ['id' => 'parent_id']);

22
core/widgets/menu/MenuWidget.php

@ -0,0 +1,22 @@
<?php
/**
* Created by Error202
* Date: 19.07.2018
*/
namespace core\widgets\menu;
use core\entities\menu\Menu;
use yii\base\Widget;
class MenuWidget extends Widget
{
public $menu_id;
public function run() {
$menu = Menu::findOne($this->menu_id);
return $this->render('menu', [
'menu' => $menu,
]);
}
}

30
core/widgets/menu/views/menu.php

@ -0,0 +1,30 @@
<?php
/**
* Created by Error202
* Date: 19.07.2018
*/
/**
* @var $this \yii\web\View
* @var $menu \core\entities\menu\Menu
*/
?>
<ul class="navbar-nav ml-auto">
<?php foreach ($menu->items as $item): ?>
<li class="<?= $item->isActive() ? 'active' : '' ?> nav-item<?= $item->hasChildren() ? ' dropdown' : '' ?>">
<?php if ($item->hasChildren() && $item->parent_id == 0): ?>
<a <?= $item->target ? 'target="'.$item->target.'"' : '' ?> href="<?= $item->getUrl() ?>" class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><?= $item->name ?></a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<?php $children = $item->children; ?>
<?php foreach ($children as $child): ?>
<a <?= $child->target ? 'target="'.$child->target.'"' : '' ?> class="dropdown-item" href="<?= $child->url ?>"><?= $child->name ?></a>
<?php endforeach; ?>
</div>
<?php elseif ($item->parent_id == 0): ?>
<a <?= $item->target ? 'target="'.$item->target.'"' : '' ?> href="<?= $item->getUrl() ?>" class="nav-link"><?= $item->name ?></a>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>

12
frontend/web/themes/start/layouts/main.php

@ -32,6 +32,15 @@ rmrevin\yii\fontawesome\cdn\AssetBundle::register($this);
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<?= \core\widgets\menu\MenuWidget::widget([
'menu_id' => 3,
]) ?>
</div>
<!--
<div class="collapse navbar-collapse" id="navbarResponsive"> <div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
@ -84,6 +93,9 @@ rmrevin\yii\fontawesome\cdn\AssetBundle::register($this);
</li> </li>
</ul> </ul>
</div> </div>
-->
</div> </div>
</nav> </nav>

28
frontend/web/themes/start/modules/pages/views/layouts/page.php

@ -0,0 +1,28 @@
<?php $this->beginContent('@frontend/web/themes/start/layouts/main.php') ?>
<!-- Page Content -->
<div class="container">
<?= \yii\widgets\Breadcrumbs::widget([
'tag' => 'ul',
'itemTemplate' => '<li class="breadcrumb-item">{link}</li>' . "\n",
'activeItemTemplate' => '<li class="breadcrumb-item active">{link}</li>' . "\n",
'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
]) ?>
<div class="row">
<!-- Page Content -->
<div class="col-md-12">
<?= $content ?>
</div>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
<?php $this->endContent() ?>

32
frontend/web/themes/start/modules/pages/views/page/view.php

@ -0,0 +1,32 @@
<?php
use yii\helpers\Html;
/* @var $this yii\web\View */
/* @var $page \common\modules\pages\entities\Page */
$this->title = $page->getSeoTitle();
$this->registerMetaTag(['name' => 'description', 'content' => $page->meta->description]);
$this->registerMetaTag(['name' => 'keywords', 'content' => $page->meta->keywords]);
foreach ($page->parents as $parent) {
if (!$parent->isRoot()) {
$this->params['breadcrumbs'][] = ['label' => $parent->title, 'url' => ['view', 'id' => $parent->id]];
}
}
$this->params['breadcrumbs'][] = $page->title;
?>
<article class="page-view">
<h1><?= Html::encode($page->title) ?></h1>
<?= Yii::$app->formatter->asHtml($page->content, [
'Attr.AllowedRel' => array('nofollow'),
'HTML.SafeObject' => true,
'Output.FlashCompat' => true,
'HTML.SafeIframe' => true,
'URI.SafeIframeRegexp'=>'%^(https?:)?//(www\.youtube(?:-nocookie)?\.com/embed/|player\.vimeo\.com/video/)%',
]) ?>
</article>
Loading…
Cancel
Save