|  |  |  | <?php
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Created by Error202
 | 
					
						
							|  |  |  |  * Date: 10.07.2018
 | 
					
						
							|  |  |  |  */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace backend\controllers;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use core\entities\menu\Menu;
 | 
					
						
							|  |  |  | use core\entities\menu\MenuItem;
 | 
					
						
							|  |  |  | use core\entities\ModuleRecord;
 | 
					
						
							|  |  |  | use core\forms\menu\MenuForm;
 | 
					
						
							|  |  |  | use core\forms\menu\MenuItemForm;
 | 
					
						
							|  |  |  | use core\forms\menu\MenuSelectForm;
 | 
					
						
							|  |  |  | use core\services\menu\MenuItemManageService;
 | 
					
						
							|  |  |  | use core\services\menu\MenuManageService;
 | 
					
						
							|  |  |  | use yii\filters\AccessControl;
 | 
					
						
							|  |  |  | use yii\filters\VerbFilter;
 | 
					
						
							|  |  |  | use yii\helpers\Json;
 | 
					
						
							|  |  |  | use yii\web\Controller;
 | 
					
						
							|  |  |  | use yii\web\NotFoundHttpException;
 | 
					
						
							|  |  |  | use Yii;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MenuController extends Controller
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  |     public $menu_service;
 | 
					
						
							|  |  |  |     public $menu_item_service;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function __construct(
 | 
					
						
							|  |  |  |         string $id,
 | 
					
						
							|  |  |  |         $module,
 | 
					
						
							|  |  |  |         MenuManageService $menu_service,
 | 
					
						
							|  |  |  |         MenuItemManageService $menu_item_service,
 | 
					
						
							|  |  |  |         array $config = []
 | 
					
						
							|  |  |  |     ) {
 | 
					
						
							|  |  |  |         parent::__construct($id, $module, $config);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $this->menu_service      = $menu_service;
 | 
					
						
							|  |  |  |         $this->menu_item_service = $menu_item_service;
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function behaviors(): array
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         return [
 | 
					
						
							|  |  |  |             'access' => [
 | 
					
						
							|  |  |  |                 'class' => AccessControl::class,
 | 
					
						
							|  |  |  |                 'rules' => [
 | 
					
						
							|  |  |  |                     [
 | 
					
						
							|  |  |  |                         'allow' => true,
 | 
					
						
							|  |  |  |                         'roles' => ['MenuManagement'],
 | 
					
						
							|  |  |  |                     ],
 | 
					
						
							|  |  |  |                     [    // all the action are accessible to admin
 | 
					
						
							|  |  |  |                         'allow' => true,
 | 
					
						
							|  |  |  |                         'roles' => ['admin'],
 | 
					
						
							|  |  |  |                     ],
 | 
					
						
							|  |  |  |                 ],
 | 
					
						
							|  |  |  |             ],
 | 
					
						
							|  |  |  |             'verbs'  => [
 | 
					
						
							|  |  |  |                 'class'   => VerbFilter::class,
 | 
					
						
							|  |  |  |                 'actions' => [
 | 
					
						
							|  |  |  |                     'delete'           => ['POST'],
 | 
					
						
							|  |  |  |                     'delete-menu-item' => ['POST'],
 | 
					
						
							|  |  |  |                 ],
 | 
					
						
							|  |  |  |             ],
 | 
					
						
							|  |  |  |         ];
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function actionIndex($id = null)
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         $menus        = []; // menu list
 | 
					
						
							|  |  |  |         $menu_records = Menu::find()->all();
 | 
					
						
							|  |  |  |         foreach ($menu_records as $menu_record) {
 | 
					
						
							|  |  |  |             $menus[$menu_record->id] = isset($menu_record->translation) && $menu_record->translation->name ? $menu_record->translation->name : $menu_record->findTranslation(Yii::$app->params['defaultLanguage'])->name;
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $form = new MenuSelectForm();
 | 
					
						
							|  |  |  |         if ($form->load(Yii::$app->request->get()) && $form->validate()) {
 | 
					
						
							|  |  |  |             return $this->redirect(['menu/index', 'id' => $form->id]);
 | 
					
						
							|  |  |  |         } elseif ($id) {
 | 
					
						
							|  |  |  |             $this->createMenuItem(); // create menu item if MenuItemForm sent
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $menu = $this->findModel($id);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             $creatorWidgets = $this->getCreatorWidgets($menu->id);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return $this->render('menu', [
 | 
					
						
							|  |  |  |                 'model'   => $form,
 | 
					
						
							|  |  |  |                 'menus'   => $menus,
 | 
					
						
							|  |  |  |                 'menu'    => $menu,
 | 
					
						
							|  |  |  |                 'creator' => $creatorWidgets,
 | 
					
						
							|  |  |  |             ]);
 | 
					
						
							|  |  |  |         } else {
 | 
					
						
							|  |  |  |             return $this->render('select_menu', [
 | 
					
						
							|  |  |  |                 'model' => $form,
 | 
					
						
							|  |  |  |                 'menus' => $menus,
 | 
					
						
							|  |  |  |             ]);
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function actionCreate()
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         $form = new MenuForm();
 | 
					
						
							|  |  |  |         if ($form->load(Yii::$app->request->post()) && $form->validate()) {
 | 
					
						
							|  |  |  |             try {
 | 
					
						
							|  |  |  |                 $menu = $this->menu_service->create($form);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return $this->redirect(['index', 'id' => $menu->id]);
 | 
					
						
							|  |  |  |             } catch (\DomainException $e) {
 | 
					
						
							|  |  |  |                 Yii::$app->errorHandler->logException($e);
 | 
					
						
							|  |  |  |                 Yii::$app->session->setFlash('error', $e->getMessage());
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->render('create', [
 | 
					
						
							|  |  |  |             'model' => $form,
 | 
					
						
							|  |  |  |         ]);
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function actionUpdate($id)
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         $menu = $this->findModel($id);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $form = new MenuForm($menu);
 | 
					
						
							|  |  |  |         if ($form->load(Yii::$app->request->post()) && $form->validate()) {
 | 
					
						
							|  |  |  |             try {
 | 
					
						
							|  |  |  |                 $this->menu_service->edit($menu->id, $form);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return $this->redirect(['index', 'id' => $menu->id]);
 | 
					
						
							|  |  |  |             } catch (\DomainException $e) {
 | 
					
						
							|  |  |  |                 Yii::$app->errorHandler->logException($e);
 | 
					
						
							|  |  |  |                 Yii::$app->session->setFlash('error', $e->getMessage());
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->render('update', [
 | 
					
						
							|  |  |  |             'model' => $form,
 | 
					
						
							|  |  |  |             'menu'  => $menu,
 | 
					
						
							|  |  |  |         ]);
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function actionDelete($id)
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         try {
 | 
					
						
							|  |  |  |             $this->menu_service->remove($id);
 | 
					
						
							|  |  |  |         } catch (\DomainException $e) {
 | 
					
						
							|  |  |  |             Yii::$app->errorHandler->logException($e);
 | 
					
						
							|  |  |  |             Yii::$app->session->setFlash('error', $e->getMessage());
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->redirect(['index']);
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function actionSaveItem($id)
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         $item = $this->findItemModel($id);
 | 
					
						
							|  |  |  |         $form = new MenuItemForm($item);
 | 
					
						
							|  |  |  |         if ($form->load(Yii::$app->request->post()) && $form->validate()) {
 | 
					
						
							|  |  |  |             try {
 | 
					
						
							|  |  |  |                 $this->menu_item_service->edit($item->id, $form);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return $this->redirect(['index', 'id' => $item->menu_id]);
 | 
					
						
							|  |  |  |             } catch (\DomainException $e) {
 | 
					
						
							|  |  |  |                 Yii::$app->errorHandler->logException($e);
 | 
					
						
							|  |  |  |                 Yii::$app->session->setFlash('error', $e->getMessage());
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $this->redirect(['index', 'id' => $item->menu_id]);
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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);
 | 
					
						
							|  |  |  |                 $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'];
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public function actionSaveMenuItems()
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         $json                       = Yii::$app->request->post('json');
 | 
					
						
							|  |  |  |         Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
 | 
					
						
							|  |  |  |         if (Yii::$app->request->isAjax) {
 | 
					
						
							|  |  |  |             try {
 | 
					
						
							|  |  |  |                 $order = [];
 | 
					
						
							|  |  |  |                 $items = Json::decode($json, true);
 | 
					
						
							|  |  |  |                 foreach ($items as $item) {
 | 
					
						
							|  |  |  |                     $order[$item[1]] = isset($order[$item[1]]) ? $order[$item[1]] + 1 : 0;
 | 
					
						
							|  |  |  |                     $this->menu_item_service->setPosition($item, $order[$item[1]]);
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  |                 Yii::$app->session->setFlash('success', Yii::t('menu', 'Menu Saved'));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return ['result' => 'success'];
 | 
					
						
							|  |  |  |             } catch (\RuntimeException $e) {
 | 
					
						
							|  |  |  |                 return ['result' => 'error', 'message' => $e->getMessage()];
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ['result' => 'error', 'message' => 'Request error'];
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function getCreatorWidgets($menu_id): array
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         $widgets = [];
 | 
					
						
							|  |  |  |         $modules = ModuleRecord::find()->active()->all();
 | 
					
						
							|  |  |  |         foreach ($modules as $module) {
 | 
					
						
							|  |  |  |             if (method_exists($module->class, 'getMenuItemCreator')) {
 | 
					
						
							|  |  |  |                 $module_widgets = call_user_func_array($module->class . '::getMenuItemCreator', [$menu_id]);
 | 
					
						
							|  |  |  |                 $widgets        = is_array($module_widgets) ? array_merge($widgets, $module_widgets) : $widgets;
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $widgets;
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private function createMenuItem()
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         $form = new MenuItemForm();
 | 
					
						
							|  |  |  |         if ($form->load(Yii::$app->request->post()) && $form->validate()) {
 | 
					
						
							|  |  |  |             try {
 | 
					
						
							|  |  |  |                 $this->menu_item_service->create($form);
 | 
					
						
							|  |  |  |             } catch (\DomainException $e) {
 | 
					
						
							|  |  |  |                 Yii::$app->errorHandler->logException($e);
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function findModel($id): Menu
 | 
					
						
							|  |  |  |     {
 | 
					
						
							|  |  |  |         if (($model = Menu::findOne($id)) !== null) {
 | 
					
						
							|  |  |  |             return $model;
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |         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.');
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 |