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.

216 lines
7.4 KiB

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