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 / Submenu.php
ameliabooking / src / Infrastructure / WP / WPMenu Last commit date
AdminBarMenu.php 1 week ago Submenu.php 1 week ago SubmenuPageHandler.php 1 month ago
Submenu.php
289 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\WP\WPMenu;
4
5 use AmeliaBooking\Domain\Services\Settings\SettingsService;
6 use AmeliaBooking\Infrastructure\Licence\Licence;
7 use AmeliaBooking\Infrastructure\WP\SettingsService\SettingsStorage;
8
9 /**
10 * Class Submenu
11 *
12 * @package AmeliaBooking\Infrastructure\WPMenu
13 */
14 class Submenu
15 {
16 /** @var SubmenuPageHandler $submenuHandler */
17 private $submenuHandler;
18
19 /** @var array $menu */
20 private $menu;
21
22 /**
23 * Submenu constructor.
24 *
25 * @param SubmenuPageHandler $submenuHandler
26 * @param array $menu
27 */
28 public function __construct($submenuHandler, $menu)
29 {
30 $this->submenuHandler = $submenuHandler;
31
32 $this->menu = $menu;
33 }
34
35 /**
36 * Add options in WP menu
37 */
38 public function addOptionsPages()
39 {
40 add_menu_page(
41 'Amelia Booking',
42 'Amelia',
43 'amelia_read_menu',
44 'amelia',
45 '',
46 AMELIA_URL . 'public/img/amelia-logo-admin-icon.svg'
47 );
48
49 foreach ($this->menu as $menu) {
50 $this->handleMenuItem($menu);
51 }
52
53 $this->addSubmenuPage(
54 'amelia',
55 'Welcome',
56 'Welcome',
57 'amelia_read_menu',
58 'wpamelia-welcome',
59 function () {
60 $this->submenuHandler->render('wpamelia-welcome');
61 }
62 );
63
64 remove_submenu_page('amelia', 'amelia');
65
66 add_action('admin_head', function () {
67 remove_submenu_page('amelia', 'wpamelia-welcome');
68 });
69
70 if (!Licence::isPremium() && current_user_can('manage_options')) {
71 $this->addUpgradeMenuItem();
72 }
73
74 add_action('admin_menu', [$this, 'applyWhiteLabelMenuBranding'], 999);
75 }
76
77 /**
78 * Apply custom plugin name and logo to the top-level Amelia admin menu.
79 */
80 public function applyWhiteLabelMenuBranding()
81 {
82 $settingsService = new SettingsService(new SettingsStorage());
83
84 $featuresIntegrations = $settingsService->getCategorySettings('featuresIntegrations');
85
86 if (!$this->isWhiteLabelFeatureEnabled($featuresIntegrations)) {
87 return;
88 }
89
90 $whiteLabel = $settingsService->getCategorySettings('whiteLabel');
91
92 if (empty($whiteLabel['pluginName']) && empty($whiteLabel['pictureFullPath']) && empty($whiteLabel['pictureThumbPath'])) {
93 return;
94 }
95
96 global $menu;
97
98 foreach ($menu as $key => $item) {
99 if (!isset($item[2]) || $item[2] !== 'amelia') {
100 continue;
101 }
102
103 if (!empty($whiteLabel['pluginName'])) {
104 $menu[$key][0] = esc_html($whiteLabel['pluginName']);
105 }
106
107 $logoUrl = !empty($whiteLabel['pictureThumbPath'])
108 ? $whiteLabel['pictureThumbPath']
109 : ($whiteLabel['pictureFullPath'] ?? '');
110
111 if (!empty($logoUrl)) {
112 $menu[$key][6] = 'none';
113 add_action('admin_head', static function () use ($logoUrl) {
114 echo '<style>#toplevel_page_amelia .wp-menu-image{background-image:url('
115 . esc_url($logoUrl)
116 . ')!important;background-size:20px 20px!important;background-position:center!important;'
117 . 'background-repeat:no-repeat!important;}</style>';
118 }, 10, 0);
119 }
120
121 break;
122 }
123 }
124
125 private function addUpgradeMenuItem()
126 {
127 $upgradeUrl = 'https://wpamelia.com/pricing/?utm_source=lite&utm_medium=dashboard&utm_content=amelia&utm_campaign=amelia-utm';
128
129 $this->addSubmenuPage(
130 'amelia',
131 '',
132 esc_html__('Upgrade', 'wpamelia'),
133 'amelia_read_menu',
134 'wpamelia-upgrade',
135 '__return_null'
136 );
137
138 add_action('admin_init', function () use ($upgradeUrl) {
139 $page = isset($_GET['page']) ? sanitize_key($_GET['page']) : '';
140
141 if ('wpamelia-upgrade' === $page) {
142 wp_redirect($upgradeUrl);
143 exit;
144 }
145 });
146
147 add_action('admin_enqueue_scripts', function () {
148 wp_enqueue_style(
149 'amelia-admin-menu',
150 AMELIA_URL . 'public/css/backend/admin-menu.css',
151 [],
152 AMELIA_VERSION
153 );
154
155 wp_enqueue_script(
156 'amelia-admin-menu',
157 AMELIA_URL . 'public/js/backend/admin-menu.js',
158 ['jquery'],
159 AMELIA_VERSION,
160 true
161 );
162 });
163 }
164
165 /**
166 * Get the inline SVG diamond icon for locked features
167 *
168 * @return string
169 */
170 private function getDiamondIcon()
171 {
172 return '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" '
173 . 'style="width: 17px; height: 16px; margin-left: 8px; vertical-align: middle; display: inline-block;">'
174 // phpcs:ignore Generic.Files.LineLength
175 . '<path fill="currentColor" d="M17.166 1c.113 0 .308-.006.498.046.149.04.29.107.415.195.16.114.28.27.352.357l4.84 5.869c.077.094.162.197.228.291.054.076.113.17.16.284l.041.122.037.178c.025.18.013.363-.037.54a1.32 1.32 0 0 1-.2.405 5.2 5.2 0 0 1-.23.291L13.265 21.712c-.11.133-.222.27-.327.377a1.316 1.316 0 0 1-.486.33 1.305 1.305 0 0 1-.903 0 1.327 1.327 0 0 1-.487-.33c-.105-.107-.217-.244-.327-.377L.73 9.577c-.078-.094-.163-.196-.23-.29a1.32 1.32 0 0 1-.2-.406 1.32 1.32 0 0 1 0-.717l.042-.122c.046-.114.105-.208.159-.284.066-.094.15-.197.229-.291l4.84-5.87c.072-.087.19-.242.35-.356l.098-.062c.099-.058.206-.103.317-.133.19-.052.386-.046.499-.046h10.332ZM12 19.198l3.416-9.925H8.584L12 19.198Zm-1.725-.402L6.997 9.273H2.422l7.853 9.523Zm3.449 0 7.854-9.523h-4.575l-3.28 9.523ZM17.01 7.773h4.568l-4.305-5.221-.043-.052h-1.959l1.739 5.273Zm-8.44 0h6.86L13.692 2.5H10.31L8.57 7.773ZM6.77 2.5l-.043.052-4.305 5.22H6.99L8.73 2.5H6.77Z"/>'
176 . '</svg>';
177 }
178
179 public function handleMenuItem(array $menu)
180 {
181 if (!isset($menu['menuSlug'])) {
182 return;
183 }
184
185 // Hide locations if it shouldn't be shown based on license and hideUnavailableFeatures setting
186 if ($menu['menuSlug'] === 'wpamelia-locations' && !Licence::shouldShowFeature('locations')) {
187 return;
188 }
189
190 // Hide custom fields if it shouldn't be shown based on license and hideUnavailableFeatures setting
191 if ($menu['menuSlug'] === 'wpamelia-customfields' && !Licence::shouldShowFeature('customFields')) {
192 return;
193 }
194
195 if ($menu['menuSlug'] === 'wpamelia-whats-new' && $this->shouldHideExternalLinks()) {
196 return;
197 }
198
199 // Add diamond icon for locked features
200 if ($menu['menuSlug'] === 'wpamelia-locations' && Licence::isFeatureLocked('locations')) {
201 $menu['menuTitle'] = '<span style="display: inline-flex; align-items: center;">'
202 . $menu['menuTitle'] . $this->getDiamondIcon() . '</span>';
203 }
204
205 if ($menu['menuSlug'] === 'wpamelia-customfields' && Licence::isFeatureLocked('customFields')) {
206 $menu['menuTitle'] = '<span style="display: inline-flex; align-items: center;">'
207 . $menu['menuTitle'] . $this->getDiamondIcon() . '</span>';
208 }
209
210 $this->addSubmenuPage(
211 $menu['parentSlug'],
212 $menu['pageTitle'],
213 $menu['menuTitle'],
214 $menu['capability'],
215 $menu['menuSlug'],
216 function () use ($menu) {
217 $this->submenuHandler->render($menu['menuSlug']);
218 }
219 );
220 }
221
222 /**
223 * @noinspection MoreThanThreeArgumentsInspection
224 *
225 * @param $parentSlug
226 * @param $pageTitle
227 * @param $menuTitle
228 * @param $capability
229 * @param $menuSlug
230 * @param string $function
231 */
232 private function addSubmenuPage($parentSlug, $pageTitle, $menuTitle, $capability, $menuSlug, $function = '')
233 {
234 add_submenu_page(
235 $parentSlug,
236 $pageTitle,
237 $menuTitle,
238 $capability,
239 $menuSlug,
240 $function
241 );
242 }
243
244 /**
245 * Check whether white label settings hide external Amelia links.
246 *
247 * @return bool
248 */
249 private function shouldHideExternalLinks()
250 {
251 $settingsService = new SettingsService(new SettingsStorage());
252
253 $featuresIntegrations = $settingsService->getCategorySettings('featuresIntegrations');
254
255 if (!$this->isWhiteLabelFeatureEnabled($featuresIntegrations)) {
256 return false;
257 }
258
259 $whiteLabel = $settingsService->getCategorySettings('whiteLabel');
260
261 return !empty($whiteLabel['hideExternalLinks']);
262 }
263
264 /**
265 * Check whether white label is enabled in settings and available in the current licence.
266 *
267 * @param array|null $featuresIntegrations
268 *
269 * @return bool
270 */
271 private function isWhiteLabelFeatureEnabled($featuresIntegrations)
272 {
273 $whiteLabelFeature = isset($featuresIntegrations['whiteLabel']) ? $featuresIntegrations['whiteLabel'] : null;
274
275 return $this->isFeatureToggleEnabled($whiteLabelFeature) &&
276 Licence::isFeatureEnabledWithLicense('whiteLabel', $whiteLabelFeature);
277 }
278
279 /**
280 * @param array|null $feature
281 */
282 private function isFeatureToggleEnabled(?array $feature): bool
283 {
284 return is_array($feature) &&
285 array_key_exists('enabled', $feature) &&
286 in_array($feature['enabled'], [true, 1, '1'], true);
287 }
288 }
289