1: <?php
2: // disable bootstrap 4
3: //SphpJsM::$jslib["bootstrap"] = 5;
4: //permissions system is also implemented, menu ban works
5: class BootstrapMenu extends \Sphp\tools\MenuGen{
6: private $brandicon = "";
7: private $navbarClasses = "navbar navbar-expand-md bg-dark navbar-dark";
8: private $navmenuClasses = "navbar-nav";
9: private $navbar = true;
10: private $fixedPos = "";
11: private $rootMenu = "root";
12: private $blnAjaxLink = false;
13: private $bootstrapversion = 5; // set bootstrap version
14: public $frontfiledir = "";
15:
16: public function __construct($filedir="") {
17: if($filedir == "") $filedir = getcwd();
18: $this->frontfiledir = $filedir;
19: parent::__construct();
20: }
21:
22: protected function onrun() {
23: $this->init();
24: $this->genMenus();
25: }
26: public function setPosition($val="sticky-top") {
27: // fixed-bottom fixed-top sticky-top
28: $this->fixedPos = $val;
29: }
30: public function setBootstrapVersion($val) {
31: $this->bootstrapversion = $val;
32: }
33: public function setRootMenu($val) {
34: $this->rootMenu = $val;
35: }
36: public function setNavBarCss($val) {
37: $this->navbarClasses = $val;
38: }
39: public function disableNavBar() {
40: $this->navbar = false;
41: }
42: public function setNavMenuCss($val) {
43: $this->navmenuClasses = $val;
44: }
45: public function setBrandIcon($val) {
46: $this->brandicon = $val;
47: }
48:
49: public function genMenus() {
50: $strmbar = $this->genMenuBar();
51: $mnuroot = $this->sphp_api->getMenuList($this->rootMenu);
52: // generate bootstrap menu
53: $str1 = "";
54: foreach ($mnuroot as $mnuName => $lstMenu) {
55: if($lstMenu[4] == ""){
56: $str1 .= $this->genMenu($lstMenu);
57: }else if(SphpBase::sphp_permissions()->isPermission($lstMenu[4])){
58: $str1 .= $this->genMenu($lstMenu);
59: }
60: }
61: $this->htmlout = $strmbar[0] . $str1 . $strmbar[1];
62: }
63: private function genMenu($lstMenu,$submenu=0){
64: $mnuroot = $this->sphp_api->getMenuList($lstMenu[0]);
65: $stra = array();
66: $str = "";
67: $str1 = "";
68: if($mnuroot != null){
69: foreach ($mnuroot as $mnuName => $lstMenu2) {
70: if($lstMenu2[4] == ""){
71: $str .= $this->genMenu($lstMenu2,1);
72: }else if(SphpBase::sphp_permissions()->isPermission($lstMenu2[4])){
73: $str .= $this->genMenu($lstMenu2,1);
74: }
75: }
76: $str1 = $this->genMenuLinks($this->sphp_api->getMenuLinkList($lstMenu[0]));
77: if($str1 != ""){
78: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[3],$submenu);
79: }else{
80: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[3],$submenu);
81: }
82: return $stra[0] . $str . $str1 . $stra[1];
83:
84: }else{
85: $str = $this->genMenuLinks($this->sphp_api->getMenuLinkList($lstMenu[0]));
86: if($str != ""){
87: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[3],$submenu);
88: }else{
89: $stra = $this->getB4Menu($lstMenu[0],$lstMenu[1],$lstMenu[3],2);
90: }
91: return $stra[0] . $str . $stra[1];
92: }
93:
94: }
95: private function genMenuLinks($mnuroot){
96: $str = "";
97: if($mnuroot != null){
98: foreach ($mnuroot as $mnuLinkName => $lstMenuLink) {
99: if($lstMenuLink[4] == ""){
100: $str .= $this->getB4MenuLink($lstMenuLink);
101: }else if(SphpBase::sphp_permissions()->isPermission($lstMenuLink[4])){
102: $str .= $this->getB4MenuLink($lstMenuLink);
103: }
104: }
105: }
106: return $str;
107: }
108: private function setAjax(){
109: $this->blnAjaxLink = true;
110: SphpBase::JSServer()->getAJAX();
111: addHeaderJSFunction('menu_ajax', "function menu_ajax(url){
112: ", " getURL(url); }");
113: }
114: private function getB4Menu($mnutext,$mnuhref="",$blnAjaxLink2=false,$mnuSub=0){
115: $mnutitle = $mnutext;
116: if($mnuhref==''){
117: $mnuhref = "#";
118: }else if($blnAjaxLink2){
119: if(!$this->blnAjaxLink){
120: $this->setAjax();
121: }
122: $mnuhref = "javascript: menu_ajax('$mnuhref');";
123: }
124: $stro = array();
125: if($mnuSub==0){
126: if($this->bootstrapversion == 5){
127: $stro[0] = '<li class="nav-item dropdown nav-dli"><a class="nav-link dropdown-toggle nav-dlink" role="button" data-bs-toggle="dropdown" aria-expanded="false" href="'.$mnuhref.'" >'.$mnutitle.'</a><ul class="dropdown-menu">';
128: }else{
129: $stro[0] = '<li class="nav-item dropdown nav-dli"><a class="nav-link dropdown-toggle nav-dlink" data-toggle="dropdown" href="'.$mnuhref.'" >'.$mnutitle.'</a><ul class="dropdown-menu">';
130: }
131: $stro[1] = '</ul></li>';
132: }else if($mnuSub==1){
133: if($this->bootstrapversion == 5){
134: $stro[0] = '<li class="dropdown-submenu nav-dli"><a class="dropdown-item dropdown-toggle nav-dlink2" role="button" data-bs-toggle="dropdown" aria-expanded="false" href="'.$mnuhref.'" >'.$mnutitle.'</a><ul class="dropdown-menu">';
135: }else{
136: $stro[0] = '<li class="dropdown-submenu nav-dli"><a class="dropdown-item dropdown-toggle nav-dlink2" data-toggle="dropdown" href="'.$mnuhref.'" >'.$mnutitle.'</a><ul class="dropdown-menu">';
137: }
138: $stro[1] = '</ul></li>';
139: }else{
140: $stro[0] = '<li class="nav-item"><a class="nav-link" href="'.$mnuhref.'" >'.$mnutitle.'</a>';
141: $stro[1] = '</li>';
142: }
143: return $stro;
144: }
145: private function getB4MenuLink($lstMenuLink){
146: $mnuitemtext = $lstMenuLink[0];
147: $mnuitemhref = $lstMenuLink[1];
148: $blnAjaxLink2 = $lstMenuLink[3];
149: $mkey = "";
150: $mkeychar = "";
151: if($lstMenuLink[5] !== ""){
152: $mkeya = $this->setKey($mnuitemtext,$lstMenuLink[5]);
153: $mkey = $mkeya[1];
154: $mkeychar = $mkeya[0];
155: }
156: $mnuitemtext = $mnuitemtext . $mkeychar;
157: $tfun = "menu_ajax";
158: if($mnuitemhref==''){
159: $mnuitemhref = "#";
160: }else if($blnAjaxLink2){
161: if(!$this->blnAjaxLink){
162: $this->setAjax();
163: }
164: if(strpos($mnuitemhref,"avascript:")<1){
165: $mnuitemhref = "javascript: $tfun('$mnuitemhref');";
166: }
167: }
168: return '<li><a class="dropdown-item" data-mkey="'. $mkey .'" href="'.$mnuitemhref.'">'.$mnuitemtext.'</a></li>';
169: }
170: public function genMenuBar() {
171: if($this->brandicon != ""){
172: $this->brandicon = ' <!-- Brand -->
173: <a class="navbar-brand" href="#"><img src="'. $this->brandicon .'" alt="Logo" style="width:40px;"></a>
174: ';
175: }
176: if($this->bootstrapversion == 5){
177: if($this->navbar){
178: $bootstrapMenu = '<nav class="'. $this->navbarClasses . ' ' . $this->fixedPos .'"><div class="container-fluid"> '. $this->brandicon .'
179: <!-- Toggler/collapsibe Button -->
180: <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#nav1" aria-controls="nav1" aria-expanded="false" aria-label="Toggle navigation">
181: <span class="navbar-toggler-icon"></span>
182: </button>
183: <div class="collapse navbar-collapse" id="nav1">
184: <ul class="'. $this->navmenuClasses .'">
185: ';
186: return array($bootstrapMenu,'</ul></div></div></nav>');
187: }else{
188: return array('<ul class="'. $this->navmenuClasses .'">','</ul>');
189:
190: }
191: }else{
192: $bootstrapMenu = '<nav class="'. $this->navbarClasses . ' ' . $this->fixedPos .'"> '. $this->brandicon .'
193: <!-- Toggler/collapsibe Button -->
194: <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#nav1">
195: <span class="navbar-toggler-icon"></span>
196: </button>
197: <div class="collapse navbar-collapse" id="nav1">
198: <ul class="'. $this->navmenuClasses .'">
199: ';
200: return array($bootstrapMenu,'</div></nav>');
201: }
202: }
203: private function setKey($mnuname,$strkeyll) {
204: $controlkeys="";
205: $keya = explode(",",$strkeyll);
206: $key = $keya[0];
207: if(count($keya)>1) $controlkeys = $keya[1];
208: $fkeya = array();
209: $fkeya["F1"] = 112;
210: $fkeya["F2"] = 113;
211: $fkeya["F3"] = 114;
212: $fkeya["F4"] = 115;
213: $fkeya["F5"] = 116;
214: $fkeya["F6"] = 117;
215: $fkeya["F7"] = 118;
216: $fkeya["F8"] = 119;
217: $fkeya["F9"] = 120;
218: $fkeya["F10"] = 121;
219: $fkeya["F11"] = 122;
220: $fkeya["F12"] = 123;
221: $mkeychar = "";
222: $controlkeysp = "";
223: if(!is_numeric($key)){
224: $mkeychar = strtoupper($key);
225: if(strlen($key)>1){
226: $key = $fkeya[$mkeychar];
227: }else{
228: $key = ord($mkeychar);
229: }
230: }else{
231: $mkeychar = strtoupper(chr($key));
232: }
233: if($controlkeys != ""){
234: $controlkeysp = "+";
235: }
236: $mkeychar = " ". strtoupper($controlkeys). $controlkeysp . $mkeychar;
237: $mkey = $key;
238: $controlkeysa = explode('+',$controlkeys);
239: $strkey = "";
240: foreach ($controlkeysa as $key => $value) {
241: if($value == "alt"){
242: if($strkey != "") $strkey .= " && ";
243: $strkey .= "eventer.event.altKey";
244: }else if($value == "ctrl"){
245: if($strkey != "") $strkey .= " && ";
246: $strkey .= "eventer.event.ctrlKey";
247: }else if($value == "shift"){
248: if($strkey != "") $strkey .= " && ";
249: $strkey .= "eventer.event.shiftKey";
250: }
251: }
252: if($strkey != "") $strkey .= " && ";
253: // code depend on key listner javascript code of framework
254: addHeaderJSFunction("jq_menukeyevent", "function jq_menukeyevent(eventer){", " return true;}",true);
255: addHeaderJSFunctionCode("jq_keyevent", "menukeyevent1", 'ret = (jq_menukeyevent(eventer2) ? ret : false);',true);
256: addHeaderJSFunctionCode("jq_menukeyevent", $mnuname, ' if('. $strkey .'eventer.keycode=='. $mkey .'){
257: if(eventer.evt==\'keyup\'){
258: $(".dropdown-item[data-mkey='.$mkey.']")[0].click();
259: }
260: return false;
261: }
262: ',true);
263: return array($mkeychar,$mkey);
264: //console.log(eventer.keycode);
265: //console.log(eventer.event.shiftKey);
266: //console.log(eventer.event.ctrlKey);
267: //console.log(eventer.event.altKey);
268: }
269:
270: private function init() {
271: $links = 'var links = $(\'.navbar ul li a\');';
272: if($this->bootstrapversion == 5){
273: $links = 'var links = $(\'.navbar div ul li a\');';
274: }
275: addHeaderJSFunctionCode("ready", "navbar", '
276: '. $links .'
277: $.each(links, function (key, va) {
278: if (va.href == document.URL) {
279: $(this).addClass(\'active\');
280: var pa = $(this).parents(\'li.nav-dli\');
281: $.each(pa, function (key2, va2) {
282: $(va2).children("a.nav-dlink:first").addClass(\'active\');
283: });
284: }
285: });
286: $(\'.dropdown-menu a.dropdown-toggle\').on(\'click\', function(e) {
287: if (!$(this).next().hasClass(\'show\')) {
288: $(this).parents(\'.dropdown-menu\').first().find(\'.show\').removeClass("show");
289: }
290: var $subMenu = $(this).next(".dropdown-menu");
291: $subMenu.toggleClass(\'show\');
292: $(this).parents(\'li.nav-item.dropdown.show\').on(\'hidden.bs.dropdown\', function(e) {
293: $(\'.dropdown-submenu .show\').removeClass("show");
294: });
295: return false;
296: });
297: //$(\'.nav-dlink\').click();
298: $.each($(\'.nav-dlink\'), function (key, va) {
299: //va.click();
300: });
301: ',true);
302: addHeaderCSS("navbar", ' .dropdown-submenu {
303: position: relative;
304: }
305:
306: .dropdown-submenu a::after {
307: transform: rotate(-90deg);
308: position: absolute;
309: right: 6px;
310: top: .8em;
311: }
312:
313: .dropdown-submenu .dropdown-menu {
314: top: 0;
315: left: 100%;
316: margin-left: .1rem;
317: margin-right: .1rem;
318: } ', true);
319:
320: }
321:
322: }
323: