PluginProbe
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution / 2.5.0
Fluent Booking – The Ultimate Appointments Scheduling, Events Booking, Events Calendar Solution v2.5.0
2.5.0 2.4.0 2.3.0 2.2.5 2.2.0 2.1.2 2.1.1 trunk 1.10.0 1.10.01 1.10.02 1.5.0 1.5.01 1.5.02 1.5.1 1.5.10 1.5.20 1.5.21 1.5.22 1.5.23 1.5.24 1.5.25 1.6.0 1.7.0 1.7.1 All 34 releases
← All changes | app/Services/Integrations/FluentBoards/Bootstrap.php +70 -36 1.5.0 → 2.5.0 View file →
@@ -9,8 +9,9 @@
9 9 use FluentBoards\App\Models\Board;
10 10 use FluentBoards\App\Models\User;
11 11 use FluentBoards\App\Services\Constant;
12 12 use FluentBoards\App\Services\NotificationService;
13 +use FluentBoards\App\Services\PermissionManager as FluentBoardsPermission;
13 14 use FluentBoards\App\Services\TaskService;
14 15 use FluentBooking\Framework\Support\Arr;
15 16 use FluentBooking\App\Http\Controllers\IntegrationManagerController;
16 17
@@ -79,8 +80,9 @@
79 80 'description' => '',
80 81 'position' => 'bottom',
81 82 'due_at_type' => 'booking',
82 83 'due_at_days' => 0,
84 + 'disable_auto_started_at' => false,
83 85 'enabled' => true
84 86 ];
85 87 }
86 88
@@ -100,36 +102,36 @@
100 102 'required' => true,
101 103 'component' => 'chained_select',
102 104 'primary_key' => 'board_id',
103 105 'fields_options' => [
104 - 'board_id' => [],
105 - 'stage_id' => [],
106 - 'label_ids' => [],
107 - 'member_ids' => [],
108 - 'priority' => []
106 + 'board_id' => [],
107 + 'stage_id' => [],
108 + 'label_ids' => [],
109 + 'member_ids' => [],
110 + 'priority' => []
109 111 ],
110 112 'options_labels' => [
111 - 'board_id' => [
113 + 'board_id' => [
112 114 'label' => __('Select Board', 'fluent-booking'),
113 115 'type' => 'select',
114 116 'placeholder' => __('Select Board', 'fluent-booking')
115 117 ],
116 - 'stage_id' => [
118 + 'stage_id' => [
117 119 'label' => __('Select Stage', 'fluent-booking'),
118 120 'type' => 'select',
119 121 'placeholder' => __('Select Stage', 'fluent-booking')
120 122 ],
121 - 'label_ids' => [
123 + 'label_ids' => [
122 124 'label' => __('Select Labels', 'fluent-booking'),
123 125 'type' => 'multi-select',
124 126 'placeholder' => __('Select Labels', 'fluent-booking')
125 127 ],
126 - 'member_ids' => [
128 + 'member_ids' => [
127 129 'label' => __('Select Assignees', 'fluent-booking'),
128 130 'type' => 'multi-select',
129 131 'placeholder' => __('Select Assignees', 'fluent-booking')
130 132 ],
131 - 'priority' => [
133 + 'priority' => [
132 134 'label' => __('Select Priority', 'fluent-booking'),
133 135 'type' => 'select',
134 136 'placeholder' => __('Priority', 'fluent-booking')
135 137 ]
@@ -171,9 +173,9 @@
171 173 'options' => [
172 174 'booking' => __('Booking Date', 'fluent-booking'),
173 175 'meeting' => __('Meeting Date', 'fluent-booking')
174 176 ]
175 - ],
177 + ],
176 178 [
177 179 'key' => 'due_at_days',
178 180 'label' => __('Due Date', 'fluent-booking'),
179 181 'tips' => __('Set the due date by entering a number relative to the booking or meeting date. Positive for days after and negative for days before the booking or meeting date.', 'fluent-booking'),
@@ -179,8 +181,16 @@
179 181 'tips' => __('Set the due date by entering a number relative to the booking or meeting date. Positive for days after and negative for days before the booking or meeting date.', 'fluent-booking'),
180 182 'component' => 'number'
181 183 ],
182 184 [
185 + 'key' => 'disable_auto_started_at',
186 + 'require_list' => false,
187 + 'label' => __('Start Date', 'fluent-booking'),
188 + 'component' => 'checkbox-single',
189 + 'checkbox_label' => __('Do not set a start date on the task', 'fluent-booking'),
190 + 'tips' => __('By default, the task start date is set to the booking creation time when a due date is present. Enable this to leave the start date empty.', 'fluent-booking'),
191 + ],
192 + [
183 193 'key' => 'position',
184 194 'label' => __('Task Position', 'fluent-booking'),
185 195 'placeholder' => __('Position', 'fluent-booking'),
186 196 'component' => 'radio_choice',
@@ -227,13 +237,17 @@
227 237 'booking_schedule_completed' => __('Booking Completed', 'fluent-booking'),
228 238 'booking_schedule_cancelled' => __('Booking Cancelled', 'fluent-booking'),
229 239 ];
230 240 }
231 -
241 +
232 242 public function getConfigFieldOptions($settings, $calendarEventId)
233 243 {
234 244 $boardId = Arr::get($settings, 'board_config.board_id');
235 245
246 + if ($boardId && !FluentBoardsPermission::userHasBoardPermission($boardId, 'GET')) {
247 + $boardId = null;
248 + }
249 +
236 250 $data = [
237 251 'board_id' => $this->getBoards(),
238 252 'stage_id' => $boardId ? $this->getStages($boardId) : [],
239 253 'label_ids' => $boardId ? $this->getBoardLabels($boardId) : [],
@@ -248,8 +262,9 @@
248 262
249 263 private function getBoards()
250 264 {
251 265 $boards = Board::whereNull('archived_at')
266 + ->whereIn('id', FluentBoardsPermission::getBoardIdsForUser())
252 267 ->select('id', 'title')
253 268 ->get();
254 269
255 270 $formattedBoards = $boards->mapWithKeys(function ($board) {
@@ -323,9 +338,9 @@
323 338
324 339 private function convertDueDate($dueTime, $dueType, $bookingStartTime)
325 340 {
326 341 $timeStamp = strtotime($bookingStartTime);
327 - $currentTime = strtotime(current_time('mysql'));
342 + $currentTime = current_time('timestamp');
328 343
329 344 if ($dueType != 'meeting') {
330 345 $timeStamp = $currentTime;
331 346 $dueTime = max(0, $dueTime);
@@ -335,29 +350,39 @@
335 350 $dateAdjustment = $adjustSign . abs($dueTime) . ' day';
336 351 $dueDate = gmdate('Y-m-d H:i:s', strtotime($dateAdjustment, $timeStamp)); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
337 352
338 353 if (strtotime($dueDate) < $currentTime) {
339 - return gmdate('Y-m-d H:i:s', $currentTime); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
354 + $dueDate = gmdate('Y-m-d H:i:s', $currentTime); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
340 355 }
341 - return $dueDate;
356 +
357 + $wpTimestamp = current_time('timestamp');
358 + $utcTimeStamp = time();
359 +
360 + $diff = $wpTimestamp - $utcTimeStamp;
361 +
362 + if (!$diff) {
363 + return $dueDate;
364 + }
365 +
366 + return gmdate('Y-m-d H:i:s', strtotime($dueDate) + $diff); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
342 367 }
343 368
344 369 public function notify($feed, $booking, $calendarEvent)
345 370 {
346 - $validData = ['task_title', 'description', 'board_config', 'author_name', 'email', 'position', 'due_at_days', 'due_at_type'];
371 + $validData = ['task_title', 'description', 'board_config', 'author_name', 'email', 'position', 'due_at_days', 'due_at_type', 'disable_auto_started_at'];
347 372 $data = Arr::only($feed['processedValues'], $validData);
348 373
349 - $boardId = intval(Arr::get($data, 'board_config.board_id'));
350 - $stageId = intval(Arr::get($data, 'board_config.stage_id'));
351 - $priority = sanitize_text_field(Arr::get($data, 'board_config.priority'));
352 - $assignees = array_map('intval', Arr::get($data, 'board_config.member_ids', []));
374 + $boardId = intval(Arr::get($data, 'board_config.board_id'));
375 + $stageId = intval(Arr::get($data, 'board_config.stage_id'));
376 + $priority = sanitize_text_field(Arr::get($data, 'board_config.priority'));
377 + $assignees = array_map('intval', Arr::get($data, 'board_config.member_ids', []));
353 378 $boardLabels = array_map('intval', Arr::get($data, 'board_config.label_ids', []));
354 - $taskTitle = sanitize_text_field(Arr::get($data, 'task_title'));
379 + $taskTitle = sanitize_text_field(Arr::get($data, 'task_title'));
355 380 $description = wp_kses_post(Arr::get($data, 'description'));
356 - $position = sanitize_text_field(Arr::get($data, 'position'));
357 - $dueAtDays = intval(Arr::get($data, 'due_at_days'));
358 - $dueAtType = sanitize_text_field(Arr::get($data, 'due_at_type'));
359 - $authorName = sanitize_text_field(Arr::get($data, 'author_name'));
381 + $position = sanitize_text_field(Arr::get($data, 'position'));
382 + $dueAtDays = intval(Arr::get($data, 'due_at_days'));
383 + $dueAtType = sanitize_text_field(Arr::get($data, 'due_at_type'));
384 + $authorName = sanitize_text_field(Arr::get($data, 'author_name'));
360 385 $authorEmail = sanitize_email(Arr::get($data, 'email'));
361 386
362 387 if (!$booking->id || !$boardId || !$stageId || !$taskTitle) {
363 388 return false;
@@ -368,19 +393,20 @@
368 393 return false;
369 394 }
370 395
371 396 $data = [
372 - 'title' => $taskTitle,
373 - 'board_id' => $boardId,
374 - 'stage_id' => $stageId,
375 - 'priority' => $priority,
376 - 'description' => $description,
377 - 'position' => $this->getLastPositionOfStageTask($boardId, $stageId),
378 - 'due_at' => $this->convertDueDate($dueAtDays, $dueAtType, $booking->start_time),
379 - 'source' => 'FluentBooking'
397 + 'title' => $taskTitle,
398 + 'board_id' => $boardId,
399 + 'stage_id' => $stageId,
400 + 'priority' => $priority,
401 + 'description' => $description,
402 + 'position' => $this->getLastPositionOfStageTask($boardId, $stageId),
403 + 'due_at' => $this->convertDueDate($dueAtDays, $dueAtType, $booking->start_time),
404 + 'source' => 'FluentBooking'
380 405 ];
381 406
382 - $data['started_at'] = $data['due_at'] ? gmdate('Y-m-d H:i:s', strtotime(current_time('mysql'))) : null; // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
407 + $disableAutoStartedAt = Arr::isTrue($feed['processedValues'], 'disable_auto_started_at');
408 + $data['started_at'] = (!$disableAutoStartedAt && $data['due_at']) ? gmdate('Y-m-d H:i:s', strtotime(current_time('mysql'))) : null; // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
383 409
384 410 $existingUser = User::where('user_email', $authorEmail)->first();
385 411 if ($existingUser) {
386 412 $data['created_by'] = $existingUser->ID;
@@ -396,8 +422,15 @@
396 422 ]
397 423 ];
398 424 }
399 425
426 + if (defined('FLUENTCRM')) {
427 + $crmConatct = \FluentCrm\App\Models\Subscriber::where('email', $authorEmail)->first();
428 + if ($crmConatct) {
429 + $data['crm_contact_id'] = $crmConatct->id;
430 + }
431 + }
432 +
400 433 $task = (new Task())->createTask($data);
401 434 if (!$task) {
402 435 return false;
403 436 }
@@ -417,9 +450,9 @@
417 450 $isEmailEnabled = (new NotificationService())->checkIfEmailEnable($assignee, Constant::BOARD_EMAIL_TASK_ASSIGN, $task->board_id);
418 451 if ($isEmailEnabled) {
419 452 (new TaskService())->sendMailAfterTaskModify('add_assignee', $assignee, $task->id);
420 453 }
421 -
454 +
422 455 do_action('fluent_boards/task_assignee_changed', $task, $assignee, 'added');
423 456 }
424 457
425 458 foreach ($boardLabels as $label) {
@@ -429,9 +462,10 @@
429 462 $taskUrl = admin_url("admin.php?page=fluent-boards#/boards/$boardId/tasks/{$task->id}");
430 463
431 464 $this->addLog(
432 465 $feed['settings']['name'],
433 - sprintf(__('Task has been created in FluentBoards. You can %s to view the task.', 'fluent-booking'), '<a target="_blank" href="' . $taskUrl . '">' . __('click here', 'fluent-booking') . '</a>'),
466 + /* translators: %s: Task URL */
467 + sprintf(__('Task has been created in FluentBoards. You can %s to view the task.', 'fluent-booking'), '<a target="_blank" href="' . $taskUrl . '">' . __('click here', 'fluent-booking') . '</a>'),
434 468 $booking->id,
435 469 'success'
436 470 );
437 471 return true;