Skip to content

Commit 4282bad

Browse files
committed
Self Generated Menus from CTT and extended use of WPBONES_TEXTDOMAIN
WIP: Add support for WPBONES_TEXTDOMAIN - Added a Menu Relations to self generated menus from CTT - Added support to make use of WPBONES_TEXTDOMAIN on Admin Menu Provider Important, this could lead to a break on your code, you *need* to add at least ``` defined("WPBONES_TEXTDOMAIN","your_text_domain"); ``` in `config.php` or update your code based on wpbones/WPKirk#32
1 parent f84eef6 commit 4282bad

File tree

2 files changed

+162
-105
lines changed

2 files changed

+162
-105
lines changed

src/Foundation/Plugin.php

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class Plugin extends Container implements PluginContract
4343
* @var string
4444
*/
4545
public $slug = '';
46+
/**
47+
* Array of Menu Relations generated by CTT
48+
* @var array
49+
*/
50+
public $menuRelations= [];
4651

4752
/**
4853
* Build in __FILE__ relative plugin.

src/Routing/AdminMenuProvider.php

+157-105
Original file line numberDiff line numberDiff line change
@@ -20,116 +20,168 @@
2020

2121
class AdminMenuProvider extends ServiceProvider
2222
{
23-
// register
24-
public function register()
25-
{
26-
$menus = include_once "{$this->plugin->basePath}/config/menus.php";
27-
28-
if (!empty($menus) && is_array($menus)) {
29-
foreach ($menus as $topLevelSlug => $menu) {
30-
// sanitize array keys
31-
$menu['position'] = isset($menu['position']) ? $menu['position'] : null;
32-
$menu['capability'] = isset($menu['capability']) ? $menu['capability'] : 'read';
33-
$menu['icon'] = isset($menu['icon']) ? $menu['icon'] : '';
34-
$page_title = isset($menu['page_title']) ? $menu['page_title'] : $menu['menu_title'];
35-
$menu['page_title'] = sanitize_title($page_title);
36-
37-
// icon
38-
$icon = $menu['icon'];
39-
$hasImage = false;
40-
41-
if (isset($menu['icon']) && !empty($menu['icon']) && 'dashicons' != substr($menu['icon'], 0, 9) && 'data:' != substr($menu['icon'], 0, 5)) {
42-
$icon = $this->plugin->images . '/' . $menu['icon'];
43-
$hasImage = true;
44-
}
45-
46-
$firstMenu = true;
47-
48-
if (substr($topLevelSlug, 0, 8) !== 'edit.php') {
49-
$suffix = add_menu_page(
50-
$menu['page_title'],
51-
$menu['menu_title'],
52-
$menu['capability'],
53-
$topLevelSlug,
54-
'',
55-
$icon,
56-
$menu['position']
57-
);
58-
59-
if ($hasImage) {
60-
add_action('admin_head', function () use ($suffix) {
61-
echo '<style>li.' . $suffix . ' div.wp-menu-image img {padding:6px 0 !important;}</style>';
62-
});
63-
}
64-
} else {
65-
$firstMenu = false;
66-
}
67-
if(!empty($menu['items'])){
68-
foreach ($menu['items'] as $key => $subMenu) {
69-
if (is_null($subMenu)) {
70-
continue;
71-
}
72-
73-
// index 0
74-
if (empty($key)) {
75-
$key = '0';
76-
}
77-
78-
// sanitize array keys
79-
$subMenu['capability'] = isset($subMenu['capability']) ? $subMenu['capability'] : $menu['capability'];
80-
$subMenu['page_title'] = isset($subMenu['page_title']) ? $subMenu['page_title'] : $subMenu['menu_title'];
81-
82-
// key could be a number
83-
$key = str_replace('-', '_', sanitize_title($key));
84-
85-
$array = explode('\\', __NAMESPACE__);
86-
$namespace = sanitize_title($array[0]);
87-
88-
// submenu slug
89-
$submenuSlug = "{$namespace}_{$key}";
90-
91-
if ($firstMenu) {
92-
$firstMenu = false;
93-
$submenuSlug = $topLevelSlug;
94-
}
95-
96-
// get hook
97-
$hook = $this->plugin->getCallableHook($subMenu['route']);
98-
99-
$subMenuHook = add_submenu_page(
100-
$topLevelSlug,
101-
$subMenu['page_title'],
102-
$subMenu['menu_title'],
103-
$subMenu['capability'],
104-
$submenuSlug,
105-
$hook
106-
);
107-
108-
if (isset($subMenu['route']['load'])) {
109-
[$controller, $method] = Str::parseCallback($subMenu['route']['load']);
110-
111-
add_action("load-{$subMenuHook}", function () use ($controller, $method) {
112-
$className = "WPKirk\\Http\\Controllers\\{$controller}";
113-
$instance = new $className();
23+
// this will help us to detect if we move some auto-assigned menu from CTT
24+
/**
25+
* Helper to know if the auto-assigned menu is in the current URL Path
26+
* @var bool
27+
*/
28+
private bool $fromLink = false;
29+
/**
30+
* The Currently Top Level Slug
31+
* @var string
32+
*/
33+
private string $topLevelSlug = "";
34+
// register
35+
public function register()
36+
{
37+
$menus = include_once "{$this->plugin->basePath}/config/menus.php";
38+
if (! empty($menus) && is_array($menus)) {
39+
40+
foreach ($menus as $topLevelSlug => $menu) {
41+
$this->topLevelSlug = $topLevelSlug;
42+
// sanitize array keys
43+
$menu['position'] = isset($menu['position']) ? $menu['position'] : null;
44+
$menu['capability'] = isset($menu['capability']) ? $menu['capability'] : 'read';
45+
$menu['icon'] = isset($menu['icon']) ? $menu['icon'] : '';
46+
$page_title = isset($menu['page_title']) ? $menu['page_title'] : $menu['menu_title'];
47+
$menu['page_title'] = sanitize_title($page_title);
48+
49+
// icon
50+
$icon = $menu['icon'];
51+
$hasImage = false;
52+
53+
if (isset($menu['icon']) && ! empty($menu['icon']) && 'dashicons' != substr($menu['icon'], 0, 9) && 'data:' != substr($menu['icon'], 0, 5)) {
54+
$icon = $this->plugin->images . '/' . $menu['icon'];
55+
$hasImage = true;
56+
}
11457

115-
return $instance->{$method}();
116-
});
117-
}
58+
$firstMenu = true;
59+
60+
if (substr($this->topLevelSlug, 0, 8) !== 'edit.php') {
61+
$suffix = add_menu_page(
62+
__($menu['page_title'], WPBONES_TEXTDOMAIN),
63+
__($menu['menu_title'], WPBONES_TEXTDOMAIN),
64+
$menu['capability'],
65+
$this->topLevelSlug,
66+
isset($menu["callback"]) ? $menu["callback"] : '',
67+
$icon,
68+
$menu['position']
69+
);
70+
71+
if ($hasImage) {
72+
add_action('admin_head', function () use ($suffix) {
73+
echo '<style>li.' . $suffix . ' div.wp-menu-image img {padding:6px 0 !important;}</style>';
74+
});
75+
}
76+
} else {
77+
$firstMenu = false;
78+
}
11879

119-
if (isset($subMenu['route']['resource'])) {
120-
$controller = $subMenu['route']['resource'];
80+
if (! empty($menu['items'])) {
81+
foreach ($menu['items'] as $key => $subMenu) {
82+
if (is_null($subMenu)) {
83+
continue;
84+
}
85+
86+
// index 0
87+
if (empty($key)) {
88+
$key = '0';
89+
}
90+
91+
// sanitize array keys
92+
$subMenu['capability'] = isset($subMenu['capability']) ? $subMenu['capability'] : $menu['capability'];
93+
$subMenu['page_title'] = isset($subMenu['page_title']) ? $subMenu['page_title'] : $subMenu['menu_title'];
94+
95+
// key could be a number
96+
$key = str_replace('-', '_', sanitize_title($key));
97+
98+
$array = explode('\\', __NAMESPACE__);
99+
$namespace = sanitize_title($array[0]);
100+
101+
// submenu slug
102+
$submenuSlug = "{$namespace}_{$key}";
103+
104+
if ($firstMenu) {
105+
$firstMenu = false;
106+
$submenuSlug = $this->topLevelSlug;
107+
}
108+
109+
// get hook
110+
if (isset($subMenu["route"])) {
111+
$hook = $this->plugin->getCallableHook($subMenu['route']);
112+
} elseif (isset($subMenu["url"])) {
113+
//if the submenu is an url, we remove the hook, and use the submenu url as target url
114+
$submenuSlug = $subMenu["url"];
115+
$hook = "";
116+
117+
}
118+
119+
$subMenuHook = add_submenu_page(
120+
$this->topLevelSlug,
121+
__($subMenu['page_title'], WPBONES_TEXTDOMAIN),
122+
__($subMenu['menu_title'], WPBONES_TEXTDOMAIN),
123+
$subMenu['capability'],
124+
$submenuSlug,
125+
$hook
126+
);
127+
128+
if (isset($subMenu['route']['load'])) {
129+
[$controller, $method] = Str::parseCallback($subMenu['route']['load']);
130+
131+
add_action("load-{$subMenuHook}", function () use ($controller, $method) {
132+
$className = "WPKirk\\Http\\Controllers\\{$controller}";
133+
$instance = new $className();
134+
135+
return $instance->{$method}();
136+
});
137+
}
138+
139+
if (isset($subMenu['route']['resource'])) {
140+
$controller = $subMenu['route']['resource'];
141+
142+
add_action("load-{$subMenuHook}", function () use ($controller) {
143+
$className = "WPKirk\\Http\\Controllers\\{$controller}";
144+
$instance = new $className();
145+
if (method_exists($instance, 'load')) {
146+
return $instance->load();
147+
}
148+
});
149+
}
150+
}
151+
}
152+
// if we had a parent menu with the same name as TopLevelSlug we will add the admin sub menu taken from CTT
153+
if (isset($this->plugin->menuRelations[$this->topLevelSlug]) && ! empty($this->plugin->menuRelations[$this->topLevelSlug])) {
154+
foreach ($this->plugin->menuRelations[$this->topLevelSlug] as $menuInternal) {
155+
if (str_contains($_SERVER['REQUEST_URI'], $menuInternal["url"])) {
156+
$this->fromLink = true;
157+
}
158+
add_submenu_page(
159+
$this->topLevelSlug,
160+
__($menuInternal['name'], WPBONES_TEXTDOMAIN),
161+
__($menuInternal['name'], WPBONES_TEXTDOMAIN),
162+
"read",
163+
$menuInternal["url"],
164+
""
165+
);
166+
remove_submenu_page("edit.php", $menuInternal["url"]);
167+
}
168+
169+
add_filter("parent_file", [$this, "renameParentFile"], 10, 1);
121170

122-
add_action("load-{$subMenuHook}", function () use ($controller) {
123-
$className = "WPKirk\\Http\\Controllers\\{$controller}";
124-
$instance = new $className();
125-
if (method_exists($instance, 'load')) {
126-
return $instance->load();
127171
}
128-
});
129-
}
172+
//if our callback is # we remove the submenu page, with this we avoid the duplicate menu and submenu with the same name
173+
if (isset($menu["callback"]) && $menu["callback"] == "#") {
174+
remove_submenu_page($this->topLevelSlug, $this->topLevelSlug);
175+
}
130176
}
131177
}
132-
}
133178
}
134-
}
179+
public function renameParentFile($parent_file)
180+
{
181+
if ($this->fromLink) {
182+
return $this->topLevelSlug;
183+
}
184+
return $parent_file;
185+
}
186+
135187
}

0 commit comments

Comments
 (0)