| 1 |
<?php |
| 2 |
|
| 3 |
namespace FluentBooking\App\Hooks\Handlers; |
| 4 |
|
| 5 |
use FluentBooking\App\App; |
| 6 |
use FluentBooking\App\Vite; |
| 7 |
use FluentBooking\App\Models\Calendar; |
| 8 |
use FluentBooking\App\Models\CalendarSlot; |
| 9 |
use FluentBooking\App\Services\DateTimeHelper; |
| 10 |
use FluentBooking\App\Services\Helper; |
| 11 |
use FluentBooking\App\Services\PermissionManager; |
| 12 |
use FluentBooking\App\Services\TransStrings; |
| 13 |
|
| 14 |
class AdminMenuHandler |
| 15 |
{ |
| 16 |
public function register() |
| 17 |
{ |
| 18 |
add_action('admin_menu', [$this, 'add']); |
| 19 |
|
| 20 |
add_action('admin_enqueue_scripts', function () { |
| 21 |
if (!isset($_REQUEST['page']) || $_REQUEST['page'] != 'fluent-booking') { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 22 |
return; |
| 23 |
} |
| 24 |
$this->enqueueAssets(); |
| 25 |
}, 100); |
| 26 |
|
| 27 |
add_action('admin_head', function () { |
| 28 |
if (!isset($_REQUEST['page']) || $_REQUEST['page'] != 'fluent-booking') { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 29 |
return; |
| 30 |
} |
| 31 |
$this->printThemeClass(); |
| 32 |
}, 1); |
| 33 |
} |
| 34 |
|
| 35 |
/** |
| 36 |
* Put the dark class on the document before the page paints. |
| 37 |
* |
| 38 |
* The theme is chosen in the browser, so the server cannot know it - which means |
| 39 |
* without this the first frame is always light, and somebody on dark gets a white flash |
| 40 |
* on every page load. This runs in <head>, before wp-admin's own markup, and is the |
| 41 |
* only reason it is inline rather than in global_admin.js: a file in the footer is too |
| 42 |
* late to matter, and one in the header is still a request the paint would wait on. |
| 43 |
* |
| 44 |
* `fluent_theme_mode` is the key every Fluent plugin shares (see global_admin.js), and it |
| 45 |
* holds a bare `light`, `dark` or `system`, so `system` is resolved here against the |
| 46 |
* machine's own preference. <body> does not exist yet, so only <html> is marked; |
| 47 |
* global_admin.js puts the same classes on <body> and #wpbody-content once it runs. |
| 48 |
* |
| 49 |
* @return void |
| 50 |
*/ |
| 51 |
public function printThemeClass() |
| 52 |
{ |
| 53 |
$script = <<<'JS' |
| 54 |
(function(){try{var s=localStorage.getItem('fluent_theme_mode')||''; |
| 55 |
if(!s){s=localStorage.getItem('fcal_color_mode')==='dark'?'dark':'light';} |
| 56 |
if(s==='system'){s='system:'+(window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light');} |
| 57 |
if(s==='dark'||s==='system:dark'){var e=document.documentElement;e.classList.add('fluent_theme_dark');e.classList.add('dark');}}catch(e){}})(); |
| 58 |
JS; |
| 59 |
|
| 60 |
echo '<script id="fluent-booking-theme-class">' . $script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 61 |
} |
| 62 |
|
| 63 |
public function add() |
| 64 |
{ |
| 65 |
$capability = PermissionManager::getMenuPermission(); |
| 66 |
$menuPriority = 26; |
| 67 |
|
| 68 |
if (defined('FLUENTCRM')) { |
| 69 |
$menuPriority = 4; |
| 70 |
} |
| 71 |
|
| 72 |
add_menu_page( |
| 73 |
__('Fluent Booking', 'fluent-booking'), |
| 74 |
__('Fluent Booking', 'fluent-booking'), |
| 75 |
$capability, |
| 76 |
'fluent-booking', |
| 77 |
[$this, 'render'], |
| 78 |
$this->getMenuIcon(), |
| 79 |
$menuPriority |
| 80 |
); |
| 81 |
|
| 82 |
add_submenu_page( |
| 83 |
'fluent-booking', |
| 84 |
__('Dashboard', 'fluent-booking'), |
| 85 |
__('Dashboard', 'fluent-booking'), |
| 86 |
$capability, |
| 87 |
'fluent-booking', |
| 88 |
[$this, 'render'] |
| 89 |
); |
| 90 |
|
| 91 |
add_submenu_page( |
| 92 |
'fluent-booking', |
| 93 |
__('Calendars', 'fluent-booking'), |
| 94 |
__('Calendars', 'fluent-booking'), |
| 95 |
$capability, |
| 96 |
'fluent-booking#/calendars', |
| 97 |
[$this, 'render'] |
| 98 |
); |
| 99 |
|
| 100 |
add_submenu_page( |
| 101 |
'fluent-booking', |
| 102 |
__('Bookings', 'fluent-booking'), |
| 103 |
__('Bookings', 'fluent-booking'), |
| 104 |
$capability, |
| 105 |
'fluent-booking#/scheduled-events', |
| 106 |
[$this, 'render'] |
| 107 |
); |
| 108 |
|
| 109 |
add_submenu_page( |
| 110 |
'fluent-booking', |
| 111 |
__('Availability', 'fluent-booking'), |
| 112 |
__('Availability', 'fluent-booking'), |
| 113 |
$capability, |
| 114 |
'fluent-booking#/availability', |
| 115 |
[$this, 'render'] |
| 116 |
); |
| 117 |
|
| 118 |
add_submenu_page( |
| 119 |
'fluent-booking', |
| 120 |
__('Settings', 'fluent-booking'), |
| 121 |
__('Settings', 'fluent-booking'), |
| 122 |
$capability, |
| 123 |
'fluent-booking#/settings/general-settings', |
| 124 |
[$this, 'render'] |
| 125 |
); |
| 126 |
} |
| 127 |
|
| 128 |
public function render() |
| 129 |
{ |
| 130 |
if (!as_has_scheduled_action('fluent_booking_five_minutes_tasks')) { |
| 131 |
as_schedule_recurring_action(time(), (60 * 5), 'fluent_booking_five_minutes_tasks', [], 'fluent-booking', true); |
| 132 |
} |
| 133 |
|
| 134 |
// The daily task carries the summary report and the MCP record purge. |
| 135 |
// A site that never got it — a secondary blog on a network activation, |
| 136 |
// or one that lost it — would grow fcal_mcp_g_* rows forever. |
| 137 |
if (!as_has_scheduled_action('fluent_booking/daily_tasks')) { |
| 138 |
as_schedule_recurring_action(time(), (60 * 60 * 24), 'fluent_booking/daily_tasks', [], 'fluent-booking', true); |
| 139 |
} |
| 140 |
|
| 141 |
$this->changeFooter(); |
| 142 |
|
| 143 |
$app = App::getInstance(); |
| 144 |
|
| 145 |
$config = $app->config; |
| 146 |
|
| 147 |
$name = $config->get('app.name'); |
| 148 |
|
| 149 |
$slug = $config->get('app.slug'); |
| 150 |
|
| 151 |
$baseUrl = Helper::getAppBaseUrl(); |
| 152 |
|
| 153 |
if (is_admin()) { |
| 154 |
$baseUrl = admin_url('admin.php?page=fluent-booking#/'); |
| 155 |
} |
| 156 |
|
| 157 |
$isNew = $this->isNew(); |
| 158 |
|
| 159 |
$menuItems = [ |
| 160 |
[ |
| 161 |
'key' => 'dashboard', |
| 162 |
'label' => $isNew ? __('Getting Started', 'fluent-booking') : __('Dashboard', 'fluent-booking'), |
| 163 |
'permalink' => $baseUrl |
| 164 |
], |
| 165 |
[ |
| 166 |
'key' => 'calendars', |
| 167 |
'label' => __('Calendars', 'fluent-booking'), |
| 168 |
'permalink' => $baseUrl . 'calendars' |
| 169 |
], |
| 170 |
[ |
| 171 |
'key' => 'scheduled-events', |
| 172 |
'label' => __('Bookings', 'fluent-booking'), |
| 173 |
'permalink' => $baseUrl . 'scheduled-events', |
| 174 |
], |
| 175 |
[ |
| 176 |
'key' => 'availability', |
| 177 |
'label' => __('Availability', 'fluent-booking'), |
| 178 |
'permalink' => $baseUrl . 'availability' |
| 179 |
] |
| 180 |
]; |
| 181 |
|
| 182 |
$settingItems = []; |
| 183 |
if (PermissionManager::userCan('manage_all_data')) { |
| 184 |
$settingItems = [ |
| 185 |
'key' => 'settings', |
| 186 |
'label' => __('Settings', 'fluent-booking'), |
| 187 |
'permalink' => $baseUrl . 'settings/general-settings' |
| 188 |
]; |
| 189 |
} |
| 190 |
|
| 191 |
$menuItems = apply_filters('fluent_booking/admin_menu_items', $menuItems); |
| 192 |
|
| 193 |
$assets = $app['url.assets']; |
| 194 |
|
| 195 |
$portalVars = apply_filters('fluent_booking/admin_portal_vars', [ |
| 196 |
'name' => $name, |
| 197 |
'slug' => $slug, |
| 198 |
'menuItems' => $menuItems, |
| 199 |
'settings' => $settingItems, |
| 200 |
'baseUrl' => $baseUrl, |
| 201 |
'logo' => $assets . 'images/logo.svg', |
| 202 |
'dark_logo' => $assets . 'images/logo_dark.svg', |
| 203 |
]); |
| 204 |
|
| 205 |
do_action('fluent_booking/admin_app_rendering'); |
| 206 |
|
| 207 |
$app->view->render('admin.menu', $portalVars); |
| 208 |
} |
| 209 |
|
| 210 |
public function changeFooter() |
| 211 |
{ |
| 212 |
add_filter('admin_footer_text', function ($content) { |
| 213 |
$url = 'https://fluentbooking.com/'; |
| 214 |
/* translators: %s: URL of the FluentBooking website */ |
| 215 |
return sprintf(wp_kses(__('Thank you for using <a href="%s">FluentBooking</a>.', 'fluent-booking'), array('a' => array('href' => array()))), esc_url($url)) . '<span title="based on your WP timezone settings" style="margin-left: 10px;" data-timestamp="' . current_time('timestamp') . '" id="fcal_server_timestamp"></span>'; |
| 216 |
}); |
| 217 |
|
| 218 |
add_filter('update_footer', function ($text) { |
| 219 |
return FLUENT_BOOKING_VERSION; |
| 220 |
}); |
| 221 |
} |
| 222 |
|
| 223 |
public function enqueueAssets() |
| 224 |
{ |
| 225 |
$app = App::getInstance(); |
| 226 |
|
| 227 |
$isRtl = Helper::fluentbooking_is_rtl(); |
| 228 |
|
| 229 |
$slug = $app->config->get('app.slug'); |
| 230 |
|
| 231 |
$assetsVersion = Vite::isDev() ? time() : FLUENT_BOOKING_ASSETS_VERSION; |
| 232 |
|
| 233 |
if ($isRtl) { |
| 234 |
Vite::enqueueStyle('fluentbooking_admin_rtl', 'admin_rtl_css', [], $assetsVersion); |
| 235 |
} |
| 236 |
|
| 237 |
add_action('wp_print_scripts', function () { |
| 238 |
|
| 239 |
$isSkip = apply_filters('fluent_booking/skip_no_conflict', false, 'scripts'); |
| 240 |
|
| 241 |
if ($isSkip) { |
| 242 |
return; |
| 243 |
} |
| 244 |
|
| 245 |
global $wp_scripts; |
| 246 |
if (!$wp_scripts) { |
| 247 |
return; |
| 248 |
} |
| 249 |
|
| 250 |
$approvedSlugs = apply_filters('fluent_booking/asset_listed_slugs', [ |
| 251 |
'\/fluent-crm\/' |
| 252 |
]); |
| 253 |
|
| 254 |
$approvedSlugs[] = '\/fluent-booking\/'; |
| 255 |
$approvedSlugs[] = '\/fluent-booking-pro\/'; |
| 256 |
|
| 257 |
$approvedSlugs = array_unique($approvedSlugs); |
| 258 |
|
| 259 |
$approvedSlugs = implode('|', $approvedSlugs); |
| 260 |
|
| 261 |
$pluginUrl = plugins_url(); |
| 262 |
|
| 263 |
$pluginUrl = str_replace(['http:', 'https:'], '', $pluginUrl); |
| 264 |
|
| 265 |
foreach ($wp_scripts->queue as $script) { |
| 266 |
if (empty($wp_scripts->registered[$script]) || empty($wp_scripts->registered[$script]->src)) { |
| 267 |
continue; |
| 268 |
} |
| 269 |
|
| 270 |
$src = $wp_scripts->registered[$script]->src; |
| 271 |
$isMatched = (strpos($src, $pluginUrl) !== false) && !preg_match('/' . $approvedSlugs . '/', $src); |
| 272 |
if (!$isMatched) { |
| 273 |
continue; |
| 274 |
} |
| 275 |
wp_dequeue_script($wp_scripts->registered[$script]->handle); |
| 276 |
} |
| 277 |
}); |
| 278 |
|
| 279 |
add_action('wp_print_styles', function () { |
| 280 |
$isSkip = apply_filters('fluent_booking/skip_no_conflict', false, 'styles'); |
| 281 |
|
| 282 |
if ($isSkip) { |
| 283 |
return; |
| 284 |
} |
| 285 |
|
| 286 |
global $wp_styles; |
| 287 |
if (!$wp_styles) { |
| 288 |
return; |
| 289 |
} |
| 290 |
|
| 291 |
$approvedSlugs = apply_filters('fluent_booking/asset_listed_slugs', [ |
| 292 |
'\/fluent-crm\/' |
| 293 |
]); |
| 294 |
|
| 295 |
$approvedSlugs[] = '\/fluent-booking\/'; |
| 296 |
$approvedSlugs[] = '\/fluent-booking-pro\/'; |
| 297 |
|
| 298 |
$approvedSlugs = array_unique($approvedSlugs); |
| 299 |
|
| 300 |
$approvedSlugs = implode('|', $approvedSlugs); |
| 301 |
|
| 302 |
$pluginUrl = plugins_url(); |
| 303 |
|
| 304 |
$themeUrl = get_theme_root_uri(); |
| 305 |
|
| 306 |
$pluginUrl = str_replace(['http:', 'https:'], '', $pluginUrl); |
| 307 |
$themeUrl = str_replace(['http:', 'https:'], '', $themeUrl); |
| 308 |
|
| 309 |
foreach ($wp_styles->queue as $script) { |
| 310 |
|
| 311 |
if (empty($wp_styles->registered[$script]) || empty($wp_styles->registered[$script]->src)) { |
| 312 |
continue; |
| 313 |
} |
| 314 |
|
| 315 |
$src = $wp_styles->registered[$script]->src; |
| 316 |
$pluginMatched = (strpos($src, $pluginUrl) !== false) && !preg_match('/' . $approvedSlugs . '/', $src); |
| 317 |
$themeMatched = (strpos($src, $themeUrl) !== false) && !preg_match('/' . $approvedSlugs . '/', $src); |
| 318 |
|
| 319 |
if (!$pluginMatched && !$themeMatched) { |
| 320 |
continue; |
| 321 |
} |
| 322 |
|
| 323 |
wp_dequeue_style($wp_styles->registered[$script]->handle); |
| 324 |
} |
| 325 |
}, 999999); |
| 326 |
|
| 327 |
Vite::enqueueStyle('fluent_booing_admin_app', 'admin_css', [], $assetsVersion, 'all'); |
| 328 |
|
| 329 |
do_action($slug . '_loading_app'); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound |
| 330 |
|
| 331 |
Vite::enqueueScript($slug . '_admin_app', 'admin_app', array('jquery'), $assetsVersion); |
| 332 |
|
| 333 |
Vite::enqueueScript($slug . '_global_admin', 'global_admin', array(), $assetsVersion); |
| 334 |
|
| 335 |
if (function_exists('wp_enqueue_editor')) { |
| 336 |
add_filter('user_can_richedit', '__return_true'); |
| 337 |
wp_enqueue_editor(); |
| 338 |
wp_enqueue_media(); |
| 339 |
} |
| 340 |
|
| 341 |
wp_localize_script($slug . '_admin_app', 'fluentFrameworkAdmin', $this->getDashboardVars($app)); |
| 342 |
} |
| 343 |
|
| 344 |
public function getDashboardVars($app) |
| 345 |
{ |
| 346 |
$assets = $app['url.assets']; |
| 347 |
$currentUser = get_user_by('ID', get_current_user_id()); |
| 348 |
|
| 349 |
$currentUsername = trim($currentUser->first_name . ' ' . $currentUser->last_name); |
| 350 |
if (!$currentUsername) { |
| 351 |
$currentUsername = $currentUser->display_name; |
| 352 |
} |
| 353 |
|
| 354 |
$isNew = $this->isNew(); |
| 355 |
|
| 356 |
$requireSlug = false; |
| 357 |
|
| 358 |
if ($isNew) { |
| 359 |
$result = $this->maybeAutoCreateCalendar($currentUser); |
| 360 |
if (!$result) { |
| 361 |
$requireSlug = true; |
| 362 |
} |
| 363 |
} |
| 364 |
|
| 365 |
$calendarId = null; |
| 366 |
|
| 367 |
$firstCalendar = Calendar::where('user_id', $currentUser->ID)->where('type', 'simple')->first(); |
| 368 |
|
| 369 |
if ($firstCalendar) { |
| 370 |
$calendarId = $firstCalendar->id; |
| 371 |
} |
| 372 |
|
| 373 |
$hasAllAccess = false; |
| 374 |
if (PermissionManager::hasAllCalendarAccess()) { |
| 375 |
$hasAllAccess = true; |
| 376 |
} |
| 377 |
|
| 378 |
$eventColors = Helper::getEventColors(); |
| 379 |
$meetingDurations = Helper::getMeetingDurations(); |
| 380 |
$multiDurations = Helper::getMeetingMultiDurations(); |
| 381 |
$durationLookup = Helper::getDurationLookup(); |
| 382 |
$multiDurationLookup = Helper::getDurationLookup(true); |
| 383 |
$scheduleSchema = Helper::getWeeklyScheduleSchema(); |
| 384 |
$bufferTimes = Helper::getBufferTimes(); |
| 385 |
$slotIntervals = Helper::getSlotIntervals(); |
| 386 |
$customFieldTypes = Helper::getCustomFieldTypes(); |
| 387 |
$weekSelectTimes = Helper::getWeekSelectTimes(); |
| 388 |
$overrideSelectTimes = Helper::getOverrideSelectTimes(); |
| 389 |
$statusChangingTimes = Helper::getBookingStatusChangingTimes(); |
| 390 |
$defaultTermsAndConditions = Helper::getDefaultTermsAndConditions(); |
| 391 |
$locationFields = (new CalendarSlot())->getLocationFields(); |
| 392 |
|
| 393 |
return apply_filters('fluent_booking/admin_vars', [ |
| 394 |
'slug' => $slug = $app->config->get('app.slug'), |
| 395 |
'nonce' => wp_create_nonce($slug), |
| 396 |
'rest' => $this->getRestInfo($app), |
| 397 |
'brand_logo' => $this->getMenuIcon(), |
| 398 |
'asset_url' => $assets, |
| 399 |
'event_colors' => $eventColors, |
| 400 |
'meeting_durations' => $meetingDurations, |
| 401 |
'multi_durations' => $multiDurations, |
| 402 |
'buffer_times' => $bufferTimes, |
| 403 |
'slot_intervals' => $slotIntervals, |
| 404 |
'schedule_schema' => $scheduleSchema, |
| 405 |
'location_fields' => $locationFields, |
| 406 |
'custom_field_types' => $customFieldTypes, |
| 407 |
'week_select_times' => $weekSelectTimes, |
| 408 |
'duration_lookup' => $durationLookup, |
| 409 |
'multi_duration_lookup' => $multiDurationLookup, |
| 410 |
'override_select_times' => $overrideSelectTimes, |
| 411 |
'status_changing_times' => $statusChangingTimes, |
| 412 |
'default_terms' => $defaultTermsAndConditions, |
| 413 |
'me' => [ |
| 414 |
'id' => $currentUser->ID, |
| 415 |
'calendar_id' => $calendarId, |
| 416 |
'full_name' => $currentUsername, |
| 417 |
'avatar' => get_avatar_url($currentUser->ID, ['size' => 96]), |
| 418 |
'email' => $currentUser->user_email, |
| 419 |
'is_admin' => $hasAllAccess, |
| 420 |
'permissions' => PermissionManager::getUserPermissions($currentUser, false), |
| 421 |
], |
| 422 |
'all_hosts' => Calendar::getAllHosts(), |
| 423 |
'is_new' => $isNew, |
| 424 |
'require_slug' => $requireSlug, |
| 425 |
'site_url' => site_url('/'), |
| 426 |
'site_title' => get_bloginfo('name'), |
| 427 |
'upgrade_url' => Helper::getUpgradeUrl(), |
| 428 |
'timezones' => DateTimeHelper::getTimeZones(true), |
| 429 |
'features' => Helper::getFeatures(), |
| 430 |
'supported_features' => apply_filters('fluent_booking/supported_featured', [ |
| 431 |
'multi_users' => true |
| 432 |
]), |
| 433 |
'i18' => [ |
| 434 |
'date_time_config' => DateTimeHelper::getI18nDateTimeConfig(), |
| 435 |
], |
| 436 |
'has_pro' => defined('FLUENT_BOOKING_PRO_DIR_FILE'), |
| 437 |
'require_upgrade' => defined('FLUENT_BOOKING_PRO_DIR_FILE') && !defined('FLUENT_BOOKING_LITE'), |
| 438 |
'dashboard_notices' => apply_filters('fluent_booking/dashboard_notices', []), |
| 439 |
'payment_methods' => apply_filters('fluent_booking/payment/get_all_methods', []), |
| 440 |
'trans' => TransStrings::getStrings(), |
| 441 |
'date_format' => DateTimeHelper::getDateFormatter(true), |
| 442 |
'time_format' => DateTimeHelper::getTimeFormatter(true), |
| 443 |
'date_time_formatter' => DateTimeHelper::getDateFormatter(true) . ', ' . DateTimeHelper::getTimeFormatter(true), |
| 444 |
'available_date_formats' => DateTimeHelper::getAvailableDateFormats(), |
| 445 |
'default_booking_filters' => Helper::getDefaultBookingFilters(), |
| 446 |
'default_paginations' => Helper::getDefaultPaginations(), |
| 447 |
'pref_settings' => Helper::getPrefSettings(), |
| 448 |
'settings_menu_items' => static::settingsMenuItems(), |
| 449 |
'admin_url' => admin_url(), |
| 450 |
'is_rtl' => Helper::fluentbooking_is_rtl(), |
| 451 |
'iframe_html' => Helper::getIframeHtml() |
| 452 |
]); |
| 453 |
} |
| 454 |
|
| 455 |
protected function getRestInfo($app) |
| 456 |
{ |
| 457 |
$ns = $app->config->get('app.rest_namespace'); |
| 458 |
$ver = $app->config->get('app.rest_version'); |
| 459 |
|
| 460 |
return [ |
| 461 |
'base_url' => esc_url_raw(rest_url()), |
| 462 |
'url' => rest_url($ns . '/' . $ver), |
| 463 |
'nonce' => wp_create_nonce('wp_rest'), |
| 464 |
'namespace' => $ns, |
| 465 |
'version' => $ver |
| 466 |
]; |
| 467 |
} |
| 468 |
|
| 469 |
protected function getMenuIcon() |
| 470 |
{ |
| 471 |
return 'data:image/svg+xml;base64,' . base64_encode('<svg width="96" height="101" viewBox="0 0 96 101" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="25.5746" width="6.39365" height="15.9841" rx="3.19683" fill="white"/><rect x="63.9365" width="6.39365" height="15.9841" rx="3.19683" fill="white"/><path fill-rule="evenodd" clip-rule="evenodd" d="M54.878 53.0655C54.544 55.6678 53.4646 58.035 51.8535 59.9427C50.1623 61.9572 47.886 63.4614 45.2863 64.1988L45.1741 64.2309L44.9203 64.2976L44.8989 64.303L24.7671 69.7V65.019C24.7671 64.9148 24.7671 64.8106 24.7778 64.7064C24.8953 62.748 26.127 61.0862 27.8476 60.3514C28.0427 60.2659 28.2431 60.1938 28.4515 60.1377L28.6412 60.0869L54.8753 53.0575V53.0655H54.878Z" fill="white"/><path fill-rule="evenodd" clip-rule="evenodd" d="M71.1411 35.8059C70.4571 41.1467 66.6178 45.5017 61.5494 46.9391L61.4372 46.9712L61.1861 47.038H61.1834L61.162 47.0433L24.7671 56.7953V52.1144C24.7671 50.0197 26.0362 48.2216 27.8476 47.4468L28.4515 47.233L28.6385 47.1823L71.1384 35.7952V35.8059H71.1411Z" fill="white"/><path fill-rule="evenodd" clip-rule="evenodd" d="M19.9802 11.1889H75.9246C83.4282 11.1889 89.5111 17.2718 89.5111 24.7754V70H95.9048V24.7754C95.9048 13.7406 86.9593 4.79523 75.9246 4.79523H19.9802C8.94542 4.79523 0 13.7406 0 24.7754V80.7198C0 91.7546 8.94542 100.7 19.9802 100.7L64.9524 100.7V94.3063H19.9802C12.4765 94.3063 6.39365 88.2234 6.39365 80.7198V24.7754C6.39365 17.2718 12.4765 11.1889 19.9802 11.1889Z" fill="white"/><path fill-rule="evenodd" clip-rule="evenodd" d="M95.9524 70.7477V69.7H64.9524V100.7H66.0001L95.9524 70.7477Z" fill="white"/></svg>'); |
| 472 |
} |
| 473 |
|
| 474 |
protected function isNew() |
| 475 |
{ |
| 476 |
return apply_filters('fluent_booking/is_new', !Calendar::first()); |
| 477 |
} |
| 478 |
|
| 479 |
/** |
| 480 |
* @param $user \WP_User |
| 481 |
* @return bool | Calendar |
| 482 |
*/ |
| 483 |
protected function maybeAutoCreateCalendar($user) |
| 484 |
{ |
| 485 |
if (!apply_filters('fluent_booking/auto_create_calendar', false, $user)) { |
| 486 |
return false; |
| 487 |
} |
| 488 |
|
| 489 |
$userName = $user->user_login; |
| 490 |
|
| 491 |
if (is_email($userName)) { |
| 492 |
$userName = explode('@', $userName); |
| 493 |
$userName = $userName[0]; |
| 494 |
} |
| 495 |
|
| 496 |
if (!Helper::isCalendarSlugAvailable($userName, true)) { |
| 497 |
return false; |
| 498 |
} |
| 499 |
|
| 500 |
$personName = trim($user->first_name . ' ' . $user->last_name); |
| 501 |
|
| 502 |
if (!$personName) { |
| 503 |
$personName = $user->display_name; |
| 504 |
} |
| 505 |
|
| 506 |
$data = [ |
| 507 |
'user_id' => $user->ID, |
| 508 |
'title' => $personName, |
| 509 |
'slug' => $userName |
| 510 |
]; |
| 511 |
|
| 512 |
return Calendar::create($data); |
| 513 |
} |
| 514 |
|
| 515 |
public static function settingsMenuItems() |
| 516 |
{ |
| 517 |
$app = App::getInstance(); |
| 518 |
$urlAssets = $app['url.assets']; |
| 519 |
|
| 520 |
return apply_filters('fluent_booking/settings_menu_items', [ |
| 521 |
'general_settings' => [ |
| 522 |
'title' => __('General', 'fluent-booking'), |
| 523 |
'disable' => false, |
| 524 |
'el_icon' => 'Operation', |
| 525 |
'component_type' => 'StandAloneComponent', |
| 526 |
'class' => 'general_settings', |
| 527 |
'route' => [ |
| 528 |
'name' => 'general_settings' |
| 529 |
] |
| 530 |
], |
| 531 |
'team_members' => [ |
| 532 |
'title' => __('Team', 'fluent-booking'), |
| 533 |
'disable' => true, |
| 534 |
'el_icon' => 'TeamIcon', |
| 535 |
'component_type' => 'StandAloneComponent', |
| 536 |
'class' => 'team_members', |
| 537 |
'route' => [ |
| 538 |
'name' => 'team_members' |
| 539 |
] |
| 540 |
], |
| 541 |
'payment_settings' => [ |
| 542 |
'title' => __('Payment', 'fluent-booking'), |
| 543 |
'disable' => true, |
| 544 |
'el_icon' => 'Money', |
| 545 |
'component_type' => 'PaymentSettingsComponent', |
| 546 |
'class' => 'payment_settings', |
| 547 |
'route' => [ |
| 548 |
'name' => 'global_payment_settings', |
| 549 |
], |
| 550 |
'children' => [ |
| 551 |
'payment_settings' => [ |
| 552 |
'title' => __('Settings', 'fluent-booking'), |
| 553 |
'disable' => true, |
| 554 |
'route' => [ |
| 555 |
'name' => 'global_payment_settings' |
| 556 |
] |
| 557 |
], |
| 558 |
'payment_methods' => [ |
| 559 |
'title' => __('Payment Methods', 'fluent-booking'), |
| 560 |
'disable' => true, |
| 561 |
'route' => [ |
| 562 |
'name' => 'payment_methods', |
| 563 |
'params' => [ |
| 564 |
'settings_key' => 'stripe' |
| 565 |
] |
| 566 |
] |
| 567 |
], |
| 568 |
'payment_coupons' => [ |
| 569 |
'title' => __('Coupons', 'fluent-booking'), |
| 570 |
'disable' => true, |
| 571 |
'route' => [ |
| 572 |
'name' => 'payment_coupons' |
| 573 |
] |
| 574 |
] |
| 575 |
], |
| 576 |
], |
| 577 |
'google' => [ |
| 578 |
'title' => __('Google Calendar / Meet', 'fluent-booking'), |
| 579 |
'disable' => true, |
| 580 |
'icon_url' => $urlAssets . 'images/gg-calendar.svg', |
| 581 |
'component_type' => 'StandAloneComponent', |
| 582 |
'class' => 'configure_google_calendar', |
| 583 |
'route' => [ |
| 584 |
'name' => 'configure-google' |
| 585 |
] |
| 586 |
], |
| 587 |
'outlook' => [ |
| 588 |
'title' => __('Outlook Calendar / MS Teams', 'fluent-booking'), |
| 589 |
'disable' => true, |
| 590 |
'icon_url' => $urlAssets . 'images/ol-icon-color.svg', |
| 591 |
'component_type' => 'GlobalSettingsComponent', |
| 592 |
'class' => 'configure_outlook_calendar', |
| 593 |
'route' => [ |
| 594 |
'name' => 'configure-integrations', |
| 595 |
'params' => [ |
| 596 |
'settings_key' => 'outlook' |
| 597 |
] |
| 598 |
] |
| 599 |
], |
| 600 |
'apple_calendar' => [ |
| 601 |
'title' => __('Apple Calendar', 'fluent-booking'), |
| 602 |
'disable' => true, |
| 603 |
'icon_url' => $urlAssets . 'images/a-cal.svg', |
| 604 |
'component_type' => 'GlobalSettingsComponent', |
| 605 |
'class' => 'configure_apple_calendar', |
| 606 |
'route' => [ |
| 607 |
'name' => 'configure-integrations', |
| 608 |
'params' => [ |
| 609 |
'settings_key' => 'apple_calendar' |
| 610 |
] |
| 611 |
] |
| 612 |
], |
| 613 |
'next_cloud_calendar' => [ |
| 614 |
'title' => __('Nextcloud Calendar', 'fluent-booking'), |
| 615 |
'disable' => true, |
| 616 |
'svg_icon' => '<svg xmlns="http://www.w3.org/2000/svg" height="800" width="1200" viewBox="-17.0838 -18.65685 148.0596 111.9411"><path d="M57.0328 0C45.2275 0 35.2216 8.0032 32.1204 18.8466c-2.6952-5.7515-8.5359-9.781-15.2633-9.781C7.6053 9.0657 0 16.671 0 25.9228c0 9.2519 7.6052 16.8606 16.857 16.8606 6.7275 0 12.5682-4.0319 15.2635-9.7844 3.1011 10.8442 13.107 18.85 24.9123 18.85 11.718 0 21.6729-7.885 24.8533-18.607 2.745 5.622 8.5135 9.5414 15.1454 9.5414 9.2518 0 16.8605-7.6087 16.8605-16.8606 0-9.2518-7.6087-16.857-16.8605-16.857-6.632 0-12.4003 3.917-15.1454 9.5378C78.7057 7.8825 68.7507 0 57.0328 0zm0 9.8955c8.9116 0 16.0307 7.1156 16.0307 16.0272s-7.119 16.0308-16.0307 16.0308c-8.9116 0-16.0272-7.1192-16.0272-16.0308S48.1212 9.8955 57.0328 9.8955zm-40.1757 9.0657c3.9044 0 6.965 3.0571 6.965 6.9615s-3.0606 6.965-6.965 6.965-6.9616-3.0606-6.9616-6.965 3.0572-6.9615 6.9616-6.9615zm80.1744 0c3.9044 0 6.965 3.0571 6.965 6.9615s-3.0606 6.965-6.965 6.965-6.9616-3.0606-6.9616-6.965 3.0572-6.9615 6.9616-6.9615z" color="currentColor" font-weight="400" font-family="sans-serif" overflow="visible" fill="currentColor"></path><path d="M29.1085 63.7615c2.7752 0 4.3275 1.9756 4.3275 4.939 0 .2822-.2352.5174-.5174.5174h-7.4792c.047 2.6342 1.8816 4.1394 3.9983 4.1394 1.3171 0 2.2579-.5644 2.7283-.9408.2822-.1881.5174-.141.6585.1412l.1411.2352c.1411.2351.094.4703-.1411.6585-.5645.4233-1.7875 1.129-3.4338 1.129-3.0575 0-5.4094-2.2109-5.4094-5.4095.047-3.3868 2.3048-5.4094 5.1272-5.4094zm2.8693 4.4216c-.094-2.1638-1.4112-3.2457-2.9164-3.2457-1.7404 0-3.2456 1.129-3.575 3.2457zm15.584-2.9164v-3.622c0-.3292.1882-.5174.5174-.5174h.3764c.3292 0 .4703.1882.4703.5174v2.446h2.1168c.3292 0 .5174.1882.5174.5174v.1412c0 .3292-.1882.4703-.5174.4703h-2.1168v5.1743c0 2.399 1.4582 2.6812 2.2579 2.7282.4233.047.5644.1411.5644.5174v.2823c0 .3292-.141.4704-.5644.4704-2.2579 0-3.622-1.3642-3.622-3.8102zm10.7718-1.5052c1.7875 0 2.9164.7526 3.4339 1.176.2351.188.2822.4233.047.7055l-.1411.2352c-.1882.2822-.4234.2822-.7056.094-.4704-.3292-1.3641-.9407-2.5871-.9407-2.2579 0-4.0453 1.6934-4.0453 4.1864 0 2.446 1.7874 4.1394 4.0453 4.1394 1.4582 0 2.446-.6585 2.9164-1.0819.2822-.1881.4704-.141.6585.1411l.1411.1882c.1411.2822.0941.4704-.141.7056-.5175.4233-1.7876 1.317-3.6691 1.317-3.0575 0-5.4094-2.2108-5.4094-5.4094.047-3.1986 2.399-5.4564 5.4564-5.4564zm6.2562-3.3398c0-.3292-.1882-.5174.141-.5174h.3764c.3293 0 .8467.1882.8467.5174V71.664c0 1.3171.6115 1.4582 1.0819 1.5053.2352 0 .4233.141.4233.4703v.3293c0 .3293-.1411.5174-.5174.5174-.8467 0-2.352-.2822-2.352-2.54zm9.6429 3.3398c3.0104 0 5.4564 2.3048 5.4564 5.3623 0 3.1046-2.446 5.4565-5.4564 5.4565-3.0105 0-5.4565-2.352-5.4565-5.4565 0-3.0575 2.446-5.3623 5.4565-5.3623zm0 9.5958c2.2108 0 3.9982-1.7875 3.9982-4.2335 0-2.3519-1.7874-4.0923-3.9982-4.0923s-4.0454 1.7875-4.0454 4.0923c.047 2.399 1.8346 4.2335 4.0454 4.2335zm23.4722-9.5958c2.493 0 3.3868 2.0697 3.3868 2.0697h.047s-.047-.3293-.047-.7997v-4.6568c0-.3293-.1412-.5174.1881-.5174h.3763c.3293 0 .8467.1881.8467.5174v13.406c0 .3292-.1411.5174-.4704.5174h-.3292c-.3293 0-.5175-.1411-.5175-.4704v-.7997c0-.3763.0941-.6585.0941-.6585h-.047s-.8938 2.1638-3.575 2.1638c-2.7752 0-4.5157-2.2108-4.5157-5.4095-.094-3.1986 1.8345-5.3623 4.5628-5.3623zm.047 9.5958c1.7404 0 3.3398-1.223 3.3398-4.1864 0-2.1167-1.082-4.1394-3.2927-4.1394-1.8345 0-3.3398 1.5052-3.3398 4.1394.047 2.54 1.3641 4.1864 3.2927 4.1864zm-85.8923.9878h.3763c.3293 0 .5174-.1881.5174-.5174V63.7274c0-1.5993 1.7404-2.7412 3.716-2.7412 1.9757 0 3.7161 1.142 3.7161 2.7412v10.1003c0 .3293.1882.5174.5174.5174h.3763c.3293 0 .4704-.1881.4704-.5174V63.6674c0-2.6812-2.6812-3.9983-5.1272-3.9983-2.3519 0-5.0331 1.317-5.0331 3.9983v10.1603c0 .3293.1411.5174.4704.5174zm78.5073-10.3485h-.3763c-.3293 0-.5175.1882-.5175.5175v5.6916c0 1.5993-1.0348 3.0575-3.0575 3.0575-1.9756 0-3.0575-1.4582-3.0575-3.0575v-5.6916c0-.3293-.1881-.5175-.5174-.5175h-.3763c-.3293 0-.4704.1882-.4704.5175v6.068c0 2.6811 1.9756 3.9982 4.4216 3.9982 2.446 0 4.4217-1.317 4.4217-3.9983v-6.068c.047-.3292-.1412-.5174-.4704-.5174zm-46.5643-.0771c-.1152.0184-.2258.0953-.3317.2214L41.5673 66.41l-1.4249 1.6978-2.1571-2.5715-1.1705-1.3955c-.1058-.1261-.2257-.195-.35-.2058-.1244-.0107-.2533.0366-.3795.1424l-.2884.2416c-.2523.2117-.2392.446-.0276.6982l1.9045 2.2693 1.5793 1.8815-2.3124 2.7553c-.0018.002-.0029.0043-.0046.0064l-1.1668 1.39c-.2117.2523-.188.5178.0643.7295l.2885.2407c.2522.2116.481.1585.6927-.0937l1.9036-2.2693 1.425-1.6977 2.157 2.5715c.0015.0016.0032.0029.0047.0046l1.1668 1.391c.2116.2521.4763.275.7285.0633l.2885-.2416c.2522-.2117.2392-.446.0275-.6983l-1.9045-2.2692-1.5792-1.8815 2.3124-2.7553c.0017-.002.0028-.0044.0046-.0064l1.1668-1.39c.2116-.2523.1879-.5179-.0643-.7295l-.2885-.2416c-.1261-.1058-.2459-.1452-.361-.1268z" fill="currentColor"></path></svg>', |
| 617 |
'component_type' => 'GlobalSettingsComponent', |
| 618 |
'class' => 'configure_nextcloud_calendar', |
| 619 |
'route' => [ |
| 620 |
'name' => 'configure-integrations', |
| 621 |
'params' => [ |
| 622 |
'settings_key' => 'next_cloud_calendar' |
| 623 |
] |
| 624 |
] |
| 625 |
], |
| 626 |
'zoom_meeting' => [ |
| 627 |
'title' => __('Zoom', 'fluent-booking'), |
| 628 |
'disable' => true, |
| 629 |
'icon_url' => $urlAssets . 'images/zoom.svg', |
| 630 |
'component_type' => 'StandAloneComponent', |
| 631 |
'class' => 'zoom_integrations', |
| 632 |
'route' => [ |
| 633 |
'name' => 'zoom_integrations' |
| 634 |
] |
| 635 |
], |
| 636 |
'twilio' => [ |
| 637 |
'title' => __('SMS by Twilio', 'fluent-booking'), |
| 638 |
'disable' => true, |
| 639 |
'svg_icon' => '<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" viewBox="0 0 24 24" id="twilio"><path d="M0,12c0,6.64,5.359,12,12,12s12-5.36,12-12c0-6.641-5.36-12-12-12C5.381-0.008,0.008,5.352,0,11.971V12z M3.199,12c-0.014-4.846,3.904-8.786,8.75-8.801H12c4.847-0.014,8.786,3.904,8.801,8.75V12c0.015,4.847-3.904,8.786-8.75,8.801H12c-4.846,0.015-8.786-3.904-8.801-8.75V12z"></path><path d="M14.959 17.44c1.361 0 2.481-1.12 2.481-2.48 0-1.359-1.12-2.48-2.481-2.479-1.359 0-2.479 1.12-2.479 2.479C12.486 16.326 13.592 17.432 14.959 17.44zM14.959 11.52c1.361 0 2.481-1.12 2.481-2.479 0-1.361-1.12-2.481-2.481-2.481-1.359 0-2.479 1.12-2.479 2.481C12.487 10.407 13.593 11.513 14.959 11.52zM9.042 17.44c1.359 0 2.479-1.12 2.479-2.48 0-1.359-1.121-2.48-2.479-2.479-1.361 0-2.481 1.12-2.481 2.479C6.567 16.327 7.674 17.433 9.042 17.44zM9.042 11.52c1.359 0 2.479-1.12 2.479-2.479 0-1.361-1.121-2.481-2.479-2.481-1.361 0-2.481 1.12-2.481 2.481C6.567 10.408 7.675 11.513 9.042 11.52z"></path></svg>', |
| 640 |
'component_type' => 'GlobalSettingsComponent', |
| 641 |
'class' => 'configure_twilio', |
| 642 |
'route' => [ |
| 643 |
'name' => 'configure-integrations', |
| 644 |
'params' => [ |
| 645 |
'settings_key' => 'twilio' |
| 646 |
] |
| 647 |
] |
| 648 |
], |
| 649 |
'license' => [ |
| 650 |
'title' => __('License', 'fluent-booking'), |
| 651 |
'disable' => true, |
| 652 |
'el_icon' => 'Lock', |
| 653 |
'component_type' => 'StandAloneComponent', |
| 654 |
'class' => 'configure_license', |
| 655 |
'route' => [ |
| 656 |
'name' => 'license' |
| 657 |
] |
| 658 |
] |
| 659 |
]); |
| 660 |
} |
| 661 |
|
| 662 |
public static function getEventSettingsMenuItems($event) |
| 663 |
{ |
| 664 |
return apply_filters('fluent_booking/calendar_event_setting_menu_items', [ |
| 665 |
'event_details' => [ |
| 666 |
'type' => 'route', |
| 667 |
'visible' => true, |
| 668 |
'disable' => false, |
| 669 |
'route' => [ |
| 670 |
'name' => 'event_details', |
| 671 |
'params' => [ |
| 672 |
'calendar_id' => $event->calendar_id, |
| 673 |
'event_id' => $event->id |
| 674 |
] |
| 675 |
], |
| 676 |
'label' => __('Event Details', 'fluent-booking'), |
| 677 |
'svgIcon' => '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M8 2V5" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M16 2V5" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M7 13H15" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M7 17H12" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M16 3.5C19.33 3.68 21 4.95 21 9.65V15.83C21 19.95 20 22.01 15 22.01H9C4 22.01 3 19.95 3 15.83V9.65C3 4.95 4.67 3.69 8 3.5H16Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/></svg>' |
| 678 |
], |
| 679 |
'assignment' => [ |
| 680 |
'type' => 'route', |
| 681 |
'visible' => false, |
| 682 |
'disable' => true, |
| 683 |
'route' => [ |
| 684 |
'name' => 'assignment', |
| 685 |
'params' => [ |
| 686 |
'calendar_id' => $event->calendar_id, |
| 687 |
'event_id' => $event->id |
| 688 |
] |
| 689 |
], |
| 690 |
'label' => __('Assignment', 'fluent-booking'), |
| 691 |
'svgIcon' => '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2 h-[16px] w-[16px] stroke-[2px] ltr:mr-2 rtl:ml-2 md:mt-px" data-testid="icon-component"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M22 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>' |
| 692 |
], |
| 693 |
'availability_settings' => [ |
| 694 |
'type' => 'route', |
| 695 |
'visible' => true, |
| 696 |
'disable' => false, |
| 697 |
'route' => [ |
| 698 |
'name' => 'availability_settings', |
| 699 |
'params' => [ |
| 700 |
'calendar_id' => $event->calendar_id, |
| 701 |
'event_id' => $event->id |
| 702 |
] |
| 703 |
], |
| 704 |
'label' => __('Availability', 'fluent-booking'), |
| 705 |
'svgIcon' => '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M6.66666 1.66699V4.16699" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M13.3333 1.66699V4.16699" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M2.91666 7.5752H17.0833" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M17.5 7.08366V14.167C17.5 16.667 16.25 18.3337 13.3333 18.3337H6.66667C3.75 18.3337 2.5 16.667 2.5 14.167V7.08366C2.5 4.58366 3.75 2.91699 6.66667 2.91699H13.3333C16.25 2.91699 17.5 4.58366 17.5 7.08366Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M13.0789 11.4167H13.0864" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M13.0789 13.9167H13.0864" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M9.99623 11.4167H10.0037" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M9.99623 13.9167H10.0037" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M6.91194 11.4167H6.91942" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M6.91194 13.9167H6.91942" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>' |
| 706 |
], |
| 707 |
'limit_settings' => [ |
| 708 |
'type' => 'route', |
| 709 |
'visible' => true, |
| 710 |
'disable' => false, |
| 711 |
'route' => [ |
| 712 |
'name' => 'limit_settings', |
| 713 |
'params' => [ |
| 714 |
'calendar_id' => $event->calendar_id, |
| 715 |
'event_id' => $event->id |
| 716 |
] |
| 717 |
], |
| 718 |
'label' => __('Limits', 'fluent-booking'), |
| 719 |
'elIcon' => 'Clock' |
| 720 |
], |
| 721 |
'question_settings' => [ |
| 722 |
'type' => 'route', |
| 723 |
'visible' => true, |
| 724 |
'disable' => false, |
| 725 |
'route' => [ |
| 726 |
'name' => 'question_settings', |
| 727 |
'params' => [ |
| 728 |
'calendar_id' => $event->calendar_id, |
| 729 |
'event_id' => $event->id |
| 730 |
] |
| 731 |
], |
| 732 |
'label' => __('Question Settings', 'fluent-booking'), |
| 733 |
'svgIcon' => '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 2V5" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M16 2V5" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M12 13.8714V13.6441C12 12.908 12.5061 12.5182 13.0121 12.2043C13.5061 11.9012 14 11.5115 14 10.797C14 9.8011 13.1085 9 12 9C10.8915 9 10 9.8011 10 10.797" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M11.9945 16.4587H12.0053" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M16 3.5C19.33 3.67504 21 4.91005 21 9.48055V15.4903C21 19.4968 20 21.5 15 21.5H9C4 21.5 3 19.4968 3 15.4903V9.48055C3 4.91005 4.67 3.68476 8 3.5H16Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/></svg>' |
| 734 |
], |
| 735 |
'email_notification' => [ |
| 736 |
'type' => 'route', |
| 737 |
'visible' => true, |
| 738 |
'disable' => false, |
| 739 |
'route' => [ |
| 740 |
'name' => 'email_notification', |
| 741 |
'params' => [ |
| 742 |
'calendar_id' => $event->calendar_id, |
| 743 |
'event_id' => $event->id |
| 744 |
] |
| 745 |
], |
| 746 |
'label' => __('Email Notification', 'fluent-booking'), |
| 747 |
'elIcon' => 'Message' |
| 748 |
], |
| 749 |
'sms_notification' => [ |
| 750 |
'type' => 'route', |
| 751 |
'visible' => true, |
| 752 |
'disable' => true, |
| 753 |
'route' => [ |
| 754 |
'name' => 'sms_notification', |
| 755 |
'params' => [ |
| 756 |
'calendar_id' => $event->calendar_id, |
| 757 |
'event_id' => $event->id |
| 758 |
] |
| 759 |
], |
| 760 |
'label' => __('SMS Notification', 'fluent-booking'), |
| 761 |
'elIcon' => 'Notification' |
| 762 |
], |
| 763 |
'recurring_settings' => [ |
| 764 |
'type' => 'route', |
| 765 |
'visible' => ($event->isOneToOne() || $event->isGroup()) ? true : false, |
| 766 |
'disable' => true, |
| 767 |
'route' => [ |
| 768 |
'name' => 'recurring_settings', |
| 769 |
'params' => [ |
| 770 |
'calendar_id' => $event->calendar_id, |
| 771 |
'event_id' => $event->id |
| 772 |
] |
| 773 |
], |
| 774 |
'label' => __('Recurring Settings', 'fluent-booking'), |
| 775 |
'svgIcon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M6 4H21C21.5523 4 22 4.44772 22 5V12H20V6H6V9L1 5L6 1V4ZM18 20H3C2.44772 20 2 19.5523 2 19V12H4V18H18V15L23 19L18 23V20Z"></path></svg>' |
| 776 |
], |
| 777 |
'advanced_settings' => [ |
| 778 |
'type' => 'route', |
| 779 |
'visible' => true, |
| 780 |
'disable' => true, |
| 781 |
'route' => [ |
| 782 |
'name' => 'advanced_settings', |
| 783 |
'params' => [ |
| 784 |
'calendar_id' => $event->calendar_id, |
| 785 |
'event_id' => $event->id |
| 786 |
] |
| 787 |
], |
| 788 |
'label' => __('Advanced Settings', 'fluent-booking'), |
| 789 |
'elIcon' => 'Operation' |
| 790 |
], |
| 791 |
'payment_settings' => [ |
| 792 |
'type' => 'route', |
| 793 |
'visible' => true, |
| 794 |
'disable' => true, |
| 795 |
'route' => [ |
| 796 |
'name' => 'payment_settings', |
| 797 |
'params' => [ |
| 798 |
'calendar_id' => $event->calendar_id, |
| 799 |
'event_id' => $event->id |
| 800 |
] |
| 801 |
], |
| 802 |
'label' => __('Payment Settings', 'fluent-booking'), |
| 803 |
'elIcon' => 'Money' |
| 804 |
], |
| 805 |
'webhook_settings' => [ |
| 806 |
'type' => 'route', |
| 807 |
'visible' => true, |
| 808 |
'disable' => true, |
| 809 |
'route' => [ |
| 810 |
'name' => 'webhook_settings', |
| 811 |
'params' => [ |
| 812 |
'calendar_id' => $event->calendar_id, |
| 813 |
'event_id' => $event->id |
| 814 |
] |
| 815 |
], |
| 816 |
'label' => __('Webhooks Feeds', 'fluent-booking'), |
| 817 |
'elIcon' => 'Link' |
| 818 |
], |
| 819 |
'integrations' => [ |
| 820 |
'type' => 'route', |
| 821 |
'visible' => true, |
| 822 |
'disable' => false, |
| 823 |
'route' => [ |
| 824 |
'name' => 'integrations', |
| 825 |
'params' => [ |
| 826 |
'calendar_id' => $event->calendar_id, |
| 827 |
'event_id' => $event->id |
| 828 |
] |
| 829 |
], |
| 830 |
'label' => __('Integrations', 'fluent-booking'), |
| 831 |
'elIcon' => 'Connection' |
| 832 |
] |
| 833 |
], $event); |
| 834 |
} |
| 835 |
|
| 836 |
public static function getCalendarSettingsMenuItems($calendar) |
| 837 |
{ |
| 838 |
return apply_filters('fluent_booking/calendar_setting_menu_items', [ |
| 839 |
'calendar_settings' => [ |
| 840 |
'type' => 'route', |
| 841 |
'visible' => true, |
| 842 |
'disable' => false, |
| 843 |
'route' => [ |
| 844 |
'name' => 'calendar_settings', |
| 845 |
'params' => [ |
| 846 |
'calendar_id' => $calendar->id |
| 847 |
] |
| 848 |
], |
| 849 |
'label' => __('Calendar Settings', 'fluent-booking'), |
| 850 |
'svgIcon' => '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/><path d="M2 12.8799V11.1199C2 10.0799 2.85 9.21994 3.9 9.21994C5.71 9.21994 6.45 7.93994 5.54 6.36994C5.02 5.46994 5.33 4.29994 6.24 3.77994L7.97 2.78994C8.76 2.31994 9.78 2.59994 10.25 3.38994L10.36 3.57994C11.26 5.14994 12.74 5.14994 13.65 3.57994L13.76 3.38994C14.23 2.59994 15.25 2.31994 16.04 2.78994L17.77 3.77994C18.68 4.29994 18.99 5.46994 18.47 6.36994C17.56 7.93994 18.3 9.21994 20.11 9.21994C21.15 9.21994 22.01 10.0699 22.01 11.1199V12.8799C22.01 13.9199 21.16 14.7799 20.11 14.7799C18.3 14.7799 17.56 16.0599 18.47 17.6299C18.99 18.5399 18.68 19.6999 17.77 20.2199L16.04 21.2099C15.25 21.6799 14.23 21.3999 13.76 20.6099L13.65 20.4199C12.75 18.8499 11.27 18.8499 10.36 20.4199L10.25 20.6099C9.78 21.3999 8.76 21.6799 7.97 21.2099L6.24 20.2199C5.33 19.6999 5.02 18.5299 5.54 17.6299C6.45 16.0599 5.71 14.7799 3.9 14.7799C2.85 14.7799 2 13.9199 2 12.8799Z" stroke="currentColor" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/></svg>' |
| 851 |
], |
| 852 |
'calendar_events' => [ |
| 853 |
'type' => 'route', |
| 854 |
'visible' => true, |
| 855 |
'disable' => false, |
| 856 |
'route' => [ |
| 857 |
'name' => 'calendar_events', |
| 858 |
'params' => [ |
| 859 |
'calendar_id' => $calendar->id |
| 860 |
] |
| 861 |
], |
| 862 |
'label' => __('Event Types', 'fluent-booking'), |
| 863 |
'svgIcon' => '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8 6H21" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 12H21" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M8 18H21" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 6H3.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 12H3.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 18H3.01" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>' |
| 864 |
], |
| 865 |
'remote_calendars' => [ |
| 866 |
'type' => 'route', |
| 867 |
'visible' => true, |
| 868 |
'disable' => true, |
| 869 |
'route' => [ |
| 870 |
'name' => 'remote_calendars', |
| 871 |
'params' => [ |
| 872 |
'calendar_id' => $calendar->id |
| 873 |
] |
| 874 |
], |
| 875 |
'label' => __('Remote Calendars', 'fluent-booking'), |
| 876 |
'svgIcon' => '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2 h-[16px] w-[16px] stroke-[2px] ltr:mr-2 rtl:ml-2 md:mt-0" data-testid="icon-component"><rect width="18" height="18" x="3" y="4" rx="2" ry="2"></rect><line x1="16" x2="16" y1="2" y2="6"></line><line x1="8" x2="8" y1="2" y2="6"></line><line x1="3" x2="21" y1="10" y2="10"></line></svg>' |
| 877 |
], |
| 878 |
'zoom_meeting' => [ |
| 879 |
'type' => 'route', |
| 880 |
'visible' => true, |
| 881 |
'disable' => true, |
| 882 |
'route' => [ |
| 883 |
'name' => 'user_zoom_integration', |
| 884 |
'params' => [ |
| 885 |
'calendar_id' => $calendar->id |
| 886 |
] |
| 887 |
], |
| 888 |
'label' => __('Zoom Integration', 'fluent-booking'), |
| 889 |
'svgIcon' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><circle cx="24" cy="24" r="20" fill="#2196f3"/><path fill="#fff" d="M29,31H14c-1.657,0-3-1.343-3-3V17h15c1.657,0,3,1.343,3,3V31z"/><polygon fill="#fff" points="37,31 31,27 31,21 37,17"/></svg>' |
| 890 |
] |
| 891 |
], $calendar); |
| 892 |
} |
| 893 |
} |
| 894 |
|
| 895 |
|