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.

205 lines
7.1 KiB

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