You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
7.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
  1. <?php
  2. namespace Wms\Menu;
  3. use Backend\Classes\Controller as BackendController;
  4. use Cms\Classes\Controller as CmsController;
  5. use Cms\Classes\Page as CmsPage;
  6. use System\Classes\PluginBase;
  7. use System\Traits\AssetMaker;
  8. /**
  9. * Menu Plugin Information File
  10. */
  11. class Plugin extends PluginBase
  12. {
  13. const ICON = 'icon-sliders';
  14. use AssetMaker;
  15. /**
  16. * @var CmsController
  17. */
  18. protected $cmsController;
  19. protected $defaultMenuName = 'wms.menu::plugin.default-menu';
  20. protected $navigation = [
  21. 'first' => null,
  22. 'sideMenu' => [],
  23. 'subMenus' => [],
  24. 'permissions' => [],
  25. ];
  26. public function pluginDetails()
  27. {
  28. return [
  29. 'name' => 'wms.menu::plugin.name',
  30. 'description' => 'wms.menu::plugin.description',
  31. 'author' => 'WMStudio',
  32. 'icon' => self::ICON,
  33. ];
  34. }
  35. public function register()
  36. {
  37. BackendController::extend(function($controller) {
  38. /* @var $controller BackendController */
  39. $controller->addDynamicMethod('getMenu', function($name) {
  40. return isset($this->navigation['subMenus'][$name]) ? $this->navigation['subMenus'][$name] : null;
  41. });
  42. });
  43. /**
  44. * Скрывает содержимое заголовка или после символа `, или между символами ``
  45. * прим:
  46. * "Заголовок `Скрытый тектс"
  47. * "`Скрытый текст` Заголовок"
  48. */
  49. CmsPage::extend(function($page) {
  50. /* @var $page CmsPage */
  51. $page->addDynamicMethod('getTitle', function($withHidden = false) use (&$page) {
  52. $title = $page->title;
  53. if (($pos = mb_strpos($title, '`')) === false) {
  54. return $title;
  55. }
  56. if ($withHidden) {
  57. return str_replace('`', '', $title);
  58. } else {
  59. $result = mb_substr($title, 0, $pos);
  60. $title = mb_substr($title, $pos + 1);
  61. if (($pos = mb_strpos($title, '`')) === false) {
  62. return $result;
  63. }
  64. return trim($result . mb_substr($title, $pos + 1));
  65. }
  66. });
  67. });
  68. \Event::listen('cms.page.beforeRenderPage', function($controller, $page) {
  69. /* @var $page CmsPage */
  70. $config = $page->theme->getConfig();
  71. $page->theme->menu = $this->getMenu(optional($config)['menu'] ?: [], !!optional($config)['pageTitleMoreImportant']);
  72. });
  73. \Event::listen('backend.page.beforeDisplay', function($controller, $action, $params) {
  74. $this->addCss('/plugins/wms/menu/assets/css/_wms_extend_menu.css');
  75. \Block::append('head', $this->makeAssets('css'));
  76. });
  77. }
  78. public function registerNavigation()
  79. {
  80. list($navigation, $defaultMenuName) = Classes\Extend::collectNavigation($this->defaultMenuName, self::ICON);
  81. if ($navigation) {
  82. $this->navigation = $navigation;
  83. }
  84. if ($defaultMenuName) {
  85. $this->defaultMenuName = $defaultMenuName;
  86. }
  87. $navigation = [];
  88. if (count($this->navigation['sideMenu'])) {
  89. \BackendMenu::registerContextSidenavPartial('Wms.Menu', 'main', '~/plugins/wms/menu/partials/menu/main/_system_sidebar.phtml');
  90. $navigation['main'] = [
  91. 'label' => 'wms.menu::plugin.name',
  92. 'url' => $this->navigation['first'] ?: \Backend::url('wms/menu'),
  93. 'icon' => self::ICON,
  94. 'permissions' => array_keys($this->navigation['permissions']),
  95. 'order' => 999, // before CMS Settings
  96. 'sideMenu' => $this->navigation['sideMenu'],
  97. ];
  98. if (is_array($this->navigation['subMenus'])) {
  99. foreach ($this->navigation['subMenus'] as $name => $menu) {
  100. if (!isset($navigation[$name])) {
  101. \BackendMenu::registerContextSidenavPartial('Wms.Menu', $name, '~/plugins/wms/menu/partials/menu/secondary/_sidenav.phtml');
  102. }
  103. }
  104. }
  105. }
  106. return $navigation;
  107. }
  108. protected function getPage($name, $title = null, $pageTitleMoreImportant = false, $active = null, $attributes = [])
  109. {
  110. /* @var $page CmsPage */
  111. if (!$this->cmsController) {
  112. $this->cmsController = CmsController::getController() ?: new CmsController;
  113. }
  114. $page = CmsPage::find($name);
  115. if (!$page) {
  116. $result = [
  117. 'url' => '#',
  118. 'name' => $title ?? $name,
  119. 'class' => optional($attributes)['class'],
  120. 'attributes' => $this->renderAttributes($attributes),
  121. ];
  122. } else {
  123. $result = [
  124. 'url' => $this->cmsController->pageUrl($name, false),
  125. 'name' => $pageTitleMoreImportant ? $page->getTitle(true) : (($title ?? $page->getTitle(true)) ?: $name),
  126. 'class' => optional($attributes)['class'],
  127. 'attributes' => $this->renderAttributes($attributes),
  128. ];
  129. }
  130. $current = CmsPage::url('');
  131. if ($current == $result['url']) {
  132. $result['active'] = true;
  133. } elseif ($active) {
  134. if (is_string($active) && $current == CmsPage::url($active)) {
  135. $result['active'] = true;
  136. } elseif (is_array($active)) {
  137. $isActive = false;
  138. foreach ($active as $page) {
  139. if ($isActive) {
  140. break;
  141. }
  142. if ($current == CmsPage::url($page)) {
  143. $isActive = true;
  144. }
  145. }
  146. if ($isActive) {
  147. $result['active'] = true;
  148. }
  149. }
  150. }
  151. return $result;
  152. }
  153. protected function getMenu($menu, $pageTitleMoreImportant = true)
  154. {
  155. $result = [];
  156. foreach ($menu as $key => $value) {
  157. if (!is_array($value)) {
  158. $result[$key] = $this->getPage($key, $value, $pageTitleMoreImportant);
  159. } else {
  160. $result[$key] = $this->getPage(
  161. $key,
  162. optional($value)['name'],
  163. $pageTitleMoreImportant,
  164. optional($value)['active'],
  165. optional($value)['attributes'] ?: []
  166. );
  167. if (isset($value['url'])) {
  168. $result[$key]['url'] = url($value['url']);
  169. }
  170. if (isset($value['pages'])) {
  171. $result[$key]['pages'] = $this->getMenu($value['pages'], $pageTitleMoreImportant);
  172. }
  173. }
  174. }
  175. return $result;
  176. }
  177. protected function renderAttributes($attributes)
  178. {
  179. $result = '';
  180. foreach ($attributes as $name => $attribute) {
  181. if ($name == 'class' || $name == 'href') {
  182. continue;
  183. }
  184. $result .= "$name=\"$attribute\" ";
  185. }
  186. if (strlen($result)) {
  187. $result = substr($result, 0, -1);
  188. }
  189. return $result;
  190. }
  191. }