PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.8
Booking for Appointments and Events Calendar – Amelia v2.4.8
2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Infrastructure / WP / WPMenu / AdminBarMenu.php
ameliabooking / src / Infrastructure / WP / WPMenu Last commit date
AdminBarMenu.php 1 week ago Submenu.php 1 week ago SubmenuPageHandler.php 1 month ago
AdminBarMenu.php
280 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\WP\WPMenu;
4
5 use AmeliaBooking\Domain\Services\Settings\SettingsService;
6 use AmeliaBooking\Infrastructure\WP\Translations\BackendStrings;
7
8 /**
9 * Class AdminBarMenu
10 *
11 * @package AmeliaBooking\Infrastructure\WP\WPMenu
12 */
13 class AdminBarMenu
14 {
15 /** @var SettingsService $settingsService */
16 private $settingsService;
17
18 /** @var bool $scriptAdded */
19 private static $scriptAdded = false;
20
21 /**
22 * AdminBarMenu constructor.
23 *
24 * @param SettingsService $settingsService
25 */
26 public function __construct($settingsService)
27 {
28 $this->settingsService = $settingsService;
29 }
30
31 /**
32 * Add Amelia menu to WordPress admin bar
33 */
34 public function addAdminBarMenu(\WP_Admin_Bar $wpAdminBar)
35 {
36 if (!current_user_can('amelia_read_menu')) {
37 return;
38 }
39
40 $pluginName = $this->getPluginName();
41 $icon = $this->getMenuIcon();
42
43 $wpAdminBar->add_menu([
44 'id' => 'amelia-menu',
45 'title' => '<span class="ab-icon">' . $icon . '</span><span class="ab-label">'
46 . esc_html($pluginName) . '</span>',
47 'href' => admin_url('admin.php?page=wpamelia-dashboard'),
48 'meta' => [
49 'title' => $pluginName,
50 'class' => 'amelia-admin-bar-menu'
51 ]
52 ]);
53
54 if (current_user_can('amelia_read_calendar')) {
55 $wpAdminBar->add_node([
56 'parent' => 'amelia-menu',
57 'id' => 'amelia-calendar',
58 'title' => BackendStrings::get('calendar'),
59 'href' => admin_url('admin.php?page=wpamelia-calendar'),
60 'meta' => [
61 'title' => BackendStrings::get('calendar')
62 ]
63 ]);
64 }
65
66 if (current_user_can('amelia_write_appointments') || current_user_can('amelia_write_events')) {
67 $wpAdminBar->add_node([
68 'parent' => 'amelia-menu',
69 'id' => 'amelia-add-booking',
70 'title' => BackendStrings::get('add_booking'),
71 'href' => '#',
72 'meta' => [
73 'title' => BackendStrings::get('add_booking')
74 ]
75 ]);
76
77 if (current_user_can('amelia_write_appointments')) {
78 $wpAdminBar->add_node([
79 'parent' => 'amelia-add-booking',
80 'id' => 'amelia-add-appointment',
81 'title' => BackendStrings::get('add_appointment'),
82 'href' => admin_url('admin.php?page=wpamelia-bookings#/book-appointment'),
83 'meta' => [
84 'title' => BackendStrings::get('add_appointment')
85 ]
86 ]);
87
88 if ($this->settingsService->isFeatureEnabled('packages')) {
89 $wpAdminBar->add_node([
90 'parent' => 'amelia-add-booking',
91 'id' => 'amelia-add-package',
92 'title' => BackendStrings::get('add_package'),
93 'href' => admin_url('admin.php?page=wpamelia-bookings#/book-package'),
94 'meta' => [
95 'title' => BackendStrings::get('add_package')
96 ]
97 ]);
98 }
99 }
100
101 if (current_user_can('amelia_write_events')) {
102 $wpAdminBar->add_node([
103 'parent' => 'amelia-add-booking',
104 'id' => 'amelia-add-event',
105 'title' => BackendStrings::get('add_event'),
106 'href' => admin_url('admin.php?page=wpamelia-bookings#/book-event'),
107 'meta' => [
108 'title' => BackendStrings::get('add_event')
109 ]
110 ]);
111 }
112 }
113
114 if (current_user_can('amelia_write_customers')) {
115 $wpAdminBar->add_node([
116 'parent' => 'amelia-menu',
117 'id' => 'amelia-add-customer',
118 'title' => BackendStrings::get('add_customer'),
119 'href' => admin_url('admin.php?page=wpamelia-customers#/manage'),
120 'meta' => [
121 'title' => BackendStrings::get('add_customer')
122 ]
123 ]);
124 }
125
126 if (current_user_can('amelia_read_settings')) {
127 $wpAdminBar->add_node([
128 'parent' => 'amelia-menu',
129 'id' => 'amelia-settings',
130 'title' => BackendStrings::get('settings'),
131 'href' => admin_url('admin.php?page=wpamelia-settings'),
132 'meta' => [
133 'title' => BackendStrings::get('settings')
134 ]
135 ]);
136 }
137 }
138
139 /**
140 * Get the display name for the admin bar menu (white label plugin name when enabled).
141 */
142 private function getPluginName(): string
143 {
144 if (!$this->settingsService->isFeatureEnabled('whiteLabel')) {
145 return 'Amelia';
146 }
147
148 $whiteLabel = $this->settingsService->getCategorySettings('whiteLabel');
149 $pluginName = !empty($whiteLabel['pluginName'])
150 ? sanitize_text_field(trim($whiteLabel['pluginName']))
151 : '';
152
153 return $pluginName !== '' ? $pluginName : 'Amelia';
154 }
155
156 /**
157 * Get the admin bar icon — white label logo when set, otherwise the default Amelia SVG.
158 */
159 private function getMenuIcon(): string
160 {
161 $logoUrl = $this->getWhiteLabelLogoUrl();
162
163 if ($logoUrl !== '') {
164 return '<img src="' . esc_url($logoUrl) . '" alt="" width="20" height="20" '
165 . 'style="vertical-align: middle; position: relative; top: 2px;" />';
166 }
167
168 return $this->getAmeliaIcon();
169 }
170
171 /**
172 * Resolve white label logo URL (thumb preferred, full as fallback).
173 */
174 private function getWhiteLabelLogoUrl(): string
175 {
176 if (!$this->settingsService->isFeatureEnabled('whiteLabel')) {
177 return '';
178 }
179
180 $whiteLabel = $this->settingsService->getCategorySettings('whiteLabel');
181
182 if (!empty($whiteLabel['pictureThumbPath'])) {
183 return $whiteLabel['pictureThumbPath'];
184 }
185
186 return !empty($whiteLabel['pictureFullPath']) ? $whiteLabel['pictureFullPath'] : '';
187 }
188
189 /**
190 * Get the inline SVG icon for Amelia
191 */
192 private function getAmeliaIcon(): string
193 {
194 $svgPath1 = 'M246.903 104.295V211.599C246.903 220.45 251.629 228.61 259.285 233.004L352.076 286.197';
195 $svgPath1 .= 'C368.474 295.598 388.878 283.725 388.878 264.792V157.996C388.878 149.188 384.194 141.049 ';
196 $svgPath1 .= '376.582 136.645L283.791 82.9336C267.392 73.4457 246.892 85.3083 246.892 104.284L246.903 104.295Z';
197
198 $svgPath2 = 'M221.57 104.295V211.599C221.57 220.45 216.844 228.61 209.188 233.004L116.397 286.197';
199 $svgPath2 .= 'C99.9988 295.598 79.5951 283.725 79.5951 264.792V157.996C79.5951 149.188 84.2788 141.049 ';
200 $svgPath2 .= '91.8912 136.645L184.682 82.9336C201.08 73.4457 221.581 85.3083 221.581 104.284L221.57 104.295Z';
201
202 $svgPath3 = 'M220.666 254.228L127.347 307.723C110.874 317.168 110.82 340.969 127.261 350.479L220.58 404.492';
203 $svgPath3 .= 'C228.192 408.896 237.57 408.896 245.172 404.492L338.49 350.479C354.932 340.969 354.878 ';
204 $svgPath3 .= '317.168 338.404 307.723L245.086 254.228C237.516 249.889 228.235 249.889 220.666 254.228Z';
205
206 return '<svg width="20" height="20" viewBox="40 62 390 370" fill="none" xmlns="http://www.w3.org/2000/svg" '
207 . 'style="vertical-align: middle; position: relative; top: 2px;">'
208 . '<path d="' . $svgPath1 . '" fill="currentColor"/>'
209 . '<path d="' . $svgPath2 . '" fill="currentColor"/>'
210 . '<path d="' . $svgPath3 . '" fill="currentColor"/>'
211 . '</svg>';
212 }
213
214 /**
215 * Enqueue admin bar menu script for both admin and frontend
216 */
217 public static function enqueueScripts()
218 {
219 if (self::$scriptAdded) {
220 return;
221 }
222
223 self::$scriptAdded = true;
224
225 $enqueueCallback = function () {
226 if (is_admin_bar_showing() && current_user_can('amelia_read_menu')) {
227 wp_enqueue_script(
228 'amelia-admin-bar-menu',
229 AMELIA_URL . 'public/js/admin-bar/admin-bar-menu.js',
230 ['jquery'],
231 AMELIA_VERSION,
232 true
233 );
234 }
235 };
236
237 add_action('admin_enqueue_scripts', $enqueueCallback);
238 add_action('wp_enqueue_scripts', $enqueueCallback);
239 add_action('admin_head', [self::class, 'addAdminBarStyles']);
240 add_action('wp_head', [self::class, 'addAdminBarStyles']);
241 }
242
243 /**
244 * Add admin bar icon styling
245 */
246 public static function addAdminBarStyles()
247 {
248 $isRtl = is_rtl();
249
250 $css = '
251 #wpadminbar #wp-admin-bar-amelia-menu > .ab-item svg {
252 color: #a7aaad;
253 }
254
255 #wpadminbar #wp-admin-bar-amelia-menu:hover > .ab-item svg {
256 color: #72aee6;
257 }
258
259 #wpadminbar #wp-admin-bar-amelia-menu > .ab-item .ab-icon img {
260 width: 20px;
261 height: 20px;
262 padding: 0;
263 object-fit: contain;
264 }
265 ';
266
267 // Add RTL-specific styles - rotate arrow 180 degrees
268 if ($isRtl) {
269 $css .= '
270 /* RTL Support: Flip submenu arrow to point left */
271 #wpadminbar li#wp-admin-bar-amelia-add-booking .ab-item .wp-admin-bar-arrow:before {
272 content: "\f141" !important;
273 }
274 ';
275 }
276
277 echo '<style>' . $css . '</style>';
278 }
279 }
280