PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.23
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.23
2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 1.45 All 41 releases
fluent-boards / app / Http / Controllers / OptionsController.php

OptionsController.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.23, at app/Http/Controllers/OptionsController.php

907 lines 33.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\App\Http\Controllers;
4
5 use FluentBoards\App\App;
6 use FluentBoards\App\Models\Meta;
7 use FluentBoards\App\Models\Task;
8 use FluentBoards\App\Models\User;
9 use FluentBoards\App\Models\Board;
10 use FluentBoards\App\Models\Relation;
11 use FluentBoards\App\Services\BoardService;
12 use FluentBoards\App\Services\Helper;
13 use FluentBoards\App\Services\OptionService;
14 use FluentBoards\App\Services\Constant;
15 use FluentBoards\App\Services\PermissionManager;
16 use FluentBoards\Framework\Http\Request\Request;
17 use FluentBoards\Framework\Support\Arr;
18 use FluentBoardsPro\App\Hooks\Handlers\ProScheduleHandler;
19
20 class OptionsController extends Controller
21 {
22 private $boardService;
23 private $optionService;
24
25 public function __construct(BoardService $boardService, OptionService $optionService)
26 {
27 parent::__construct();
28 $this->boardService = $boardService;
29 $this->optionService = $optionService;
30 }
31
32 public function selectorOptions(Request $request)
33 {
34 try {
35 $optionKey = $request->getSafe('option_key');
36 $search = $request->getSafe('search');
37 $includedIds = $request->getSafe('values');
38 $boardId = $request->getSafe('board_id');
39
40 $options = [];
41 if ('users' === $optionKey || 'task_assignees' === $optionKey) { // no ajax/code is designed to handle this eventually will goto else
42
43 if (!PermissionManager::isBoardManager($boardId)) {
44 throw new \Exception('You do not have permission to access this route');
45 }
46
47 if (!defined('FLUENT_BOARDS_PRO')) {
48 // get who has 'manage_options' capability
49 $users = PermissionManager::getAll_WP_Admins($search);
50
51 } else {
52 // Search by user login, email, and nicename, first_name , last_name
53 $users = Helper::searchWordPressUsers($search);
54 $users = Helper::sanitizeUsersArray($users, $boardId);
55
56 }
57
58 $options = $this->addUserDataAsSelectorOption($users);
59
60 } elseif ('boards' === $optionKey) {
61 $boards = Board::query()
62 ->when($search, function ($query) use ($search) {
63 return $query->where('title', 'LIKE', '%' . $search . '%');
64 })->take(20)->get();
65
66 foreach ($boards as $board) {
67 $options[] = [
68 'id' => $board->id,
69 'title' => $board->title,
70 'left_side_value' => $board->title,
71 'right_side_value' => $board->slug,
72 ];
73 }
74 } elseif ('tasks' === $optionKey) {
75 $tasks = Task::where('board_id', $boardId)
76 ->whereNull('archived_at')
77 ->whereNull('parent_id')
78 ->when($search, function ($query) use ($search) {
79 return $query->where('title', 'LIKE', '%' . $search . '%');
80 })->take(20)->get();
81
82 foreach ($tasks as $task) {
83 $options[] = [
84 'id' => $task->id,
85 'title' => $task->title,
86 'board_id' => $task->board_id
87 ];
88 }
89
90 } elseif ('assigned_in_task' == $optionKey) {
91 $users = (new BoardService())->getAssigneesByBoard($boardId, $search);
92 $options = $this->addUserDataAsSelectorOption($users);
93 } else {
94 $options = apply_filters('fluent_boards/ajax_options_' . $optionKey, [], $search, $includedIds);
95 }
96
97 return $this->sendSuccess([
98 'options' => $options,
99 ], 200);
100 } catch (\Exception $e) {
101 return $this->sendError($e->getMessage(), 404);
102 }
103 }
104
105 private function addUserDataAsSelectorOption($users)
106 {
107 $options = [];
108 foreach ($users as $user) {
109 $options[] = [
110 'id' => $user->ID,
111 'email' => $user->user_email,
112 'name' => $user->display_name ?? $user->user_email,
113 'title' => $user->display_name . ' (' . $user->user_email . ')',
114 'photo' => get_avatar_url($user->user_email),
115 ];
116 }
117 return $options;
118 }
119
120 public function getCurrentUserPermissions()
121 {
122 try {
123 $currentUserBoards = Relation::query()
124 ->where('user_id', get_current_user_id())
125 ->whereNotNull('board_id')
126 ->where('status', 'ACTIVE')
127 ->get();
128 foreach ($currentUserBoards as &$currentUserBoardPermission) {
129 $currentUserBoardPermission->permissions = \maybe_unserialize($currentUserBoardPermission->permissions);
130 }
131
132 return $this->sendSuccess(
133 $currentUserBoards, 200
134 );
135 } catch (\Exception $e) {
136 return $this->sendError($e->getMessage(), 404);
137 }
138 }
139
140 public function getUserPermission(Request $request)
141 {
142 try {
143 $boardId = $request->getSafe('boardId');
144 $userId = $request->getSafe('userId');
145
146 $boardUser = Relation::where('board_id', $boardId)
147 ->where('user_id', $userId)
148 ->where('status', 'ACTIVE')->first();
149 if (!$boardUser->is_admin) {
150 $boardUser->permissions = \maybe_unserialize($boardUser->permissions);
151 }
152
153 return $this->sendSuccess(
154 $boardUser, 200
155 );
156 } catch (\Exception $e) {
157 return $this->sendError($e->getMessage(), 404);
158 }
159 }
160
161 public function updatedUserPermission(Request $request)
162 {
163 try {
164 $permission = $request->getSafe('userPermission');
165 $updateType = $request->getSafe('updateType');
166 $boardId = $request->getSafe('boardId');
167 $userId = $request->getSafe('userId');
168
169 $boardUser = Relation::where('board_id', $boardId)->where('user_id', $userId)->status('ACTIVE')->first();
170
171 if ('Board Admin' == $permission) {
172 $boardUser->is_admin = 'add' == $updateType ? 1 : 0;
173 $boardUser->save();
174 } else {
175 if (0 == $boardUser->is_admin) {
176 $permissionsAlreadyHave = maybe_unserialize($boardUser->permissions);
177 if (!in_array($permission, $permissionsAlreadyHave) && 'add' == $updateType) {
178 array_push($permissionsAlreadyHave, $permission);
179 } elseif (in_array($permission, $permissionsAlreadyHave) && 'remove' == $updateType) {
180 if (($key = array_search($permission, $permissionsAlreadyHave)) !== false) {
181 unset($permissionsAlreadyHave[$key]);
182 }
183 }
184 $boardUser->permissions = serialize($permissionsAlreadyHave);
185 $boardUser->save();
186 }
187 }
188
189 $boardUser->permissions = maybe_unserialize($boardUser->permissions);
190
191 return $this->sendSuccess(
192 $boardUser, 200
193 );
194 } catch (\Exception $e) {
195 return $this->sendError($e->getMessage(), 404);
196 }
197 }
198
199 public function SetUserSuperAdmin($userId)
200 {
201 try {
202 $this->optionService->createSuperAdmin($userId);
203 return $this->sendSuccess([
204 'message' => __('Member has been set super admin successfully!', 'fluent-boards')
205 ], 200);
206
207 } catch (\Exception $e) {
208 return $this->sendError($e->getMessage(), 404);
209 }
210 }
211
212 public function removeUserSuperAdmin($userId)
213 {
214 try {
215 $this->optionService->removeUserSuperAdmin($userId);
216
217 return $this->sendSuccess([
218 'message' => __('User has been removed as super admin successfully!', 'fluent-boards'),
219 ], 200);
220 } catch (\Exception $e) {
221 return $this->sendError($e->getMessage(), 404);
222 }
223 }
224
225 public function IsUserAllBoardAdmin(Request $request)
226 {
227 try {
228 $userId = $request->getSafe('id');
229 $isSuperAdmin = false;
230 $superAdmin = Relation::where('board_id', null)->where('user_id', $userId)->where('status', 'ACTIVE')->first();
231 $totalSuperAdmin = Relation::where('board_id', null)->where('status', 'ACTIVE')->count();
232 $permissions = [];
233 if ($superAdmin) {
234 $isSuperAdmin = true;
235 $permissions = \maybe_unserialize($superAdmin->permissions);
236 }
237
238 return $this->sendSuccess([
239 'allBoardAdmin' => $isSuperAdmin,
240 'permissions' => $permissions,
241 'numberOfSuperAdmin' => $totalSuperAdmin,
242 ], 200);
243 } catch (\Exception $e) {
244 return $this->sendError($e->getMessage(), 404);
245 }
246 }
247
248 public function RemoveUserFromSuperAdmin(Request $request, $id)
249 {
250 try {
251 $userId = $request->getSafe('id');
252
253 $superAdmin = Relation::where('board_id', null)->where('user_id', $userId)->first();
254 $superAdmin->status = 'INACTIVE';
255 $superAdmin->save();
256
257 return $this->sendSuccess([
258 'message' => __('User removed as super admin', 'fluent-boards'),
259 ], 201);
260 } catch (\Exception $e) {
261 return $this->sendError($e->getMessage(), 404);
262 }
263 }
264
265 public function removeUserFromBoard(Request $request)
266 {
267 try {
268 $boardId = $request->getSafe('boardId');
269 $userId = $request->getSafe('userId');
270
271 $this->boardService->removeUserFromBoard($boardId, $userId);
272
273 if (!PermissionManager::isAdmin($userId)) {
274 $this->boardService->removeFromRecentlyOpened($boardId, $userId);
275 }
276
277 return $this->sendSuccess([
278 'message' => __('User Removed from Board successfully!', 'fluent-boards'),
279 ], 201);
280 } catch (\Exception $e) {
281 return $this->sendError($e->getMessage(), 404);
282 }
283 }
284
285 public function addAsSuperAdmin(Request $request)
286 {
287 try {
288 $userIds = $request->getSafe('memberIds');
289 foreach ($userIds as $userId) {
290 $this->createSuperAdmin($userId);
291 }
292
293 return $this->sendSuccess([
294 'message' => __('Fluent boards admin added', 'fluent-boards'),
295 ], 201);
296 } catch (\Exception $e) {
297 return $this->sendError($e->getMessage(), 404);
298 }
299 }
300
301 private function createSuperAdmin($userId)
302 {
303 try {
304 $existUser = Meta::where('object_id', $userId)->first();
305 if (!$existUser) {
306 $meta = new Meta();
307 $meta->object_id = $userId;
308 $meta->object_type = Constant::FLUENT_BOARD_ADMIN;
309 $meta->save();
310 }
311 } catch (\Exception $e) {
312 return $this->sendError($e->getMessage(), 404);
313 }
314 }
315
316 public function addMembersInBoards(Request $request)
317 {
318 try {
319 $userIds = $request->getSafe('memberIds');
320 $boardIds = $request->getSafe('boardIds');
321
322 foreach ($userIds as $userId) {
323 foreach ($boardIds as $boardId) {
324 $this->boardService->addMembersInBoard($boardId, $userId);
325 }
326 }
327
328 return $this->sendSuccess([
329 'message' => __('Members added to boards', 'fluent-boards'),
330 ], 201);
331 } catch (\Exception $e) {
332 return $this->sendError($e->getMessage(), 404);
333 }
334 }
335
336
337 public function updateGlobalNotificationSettings(Request $request)
338 {
339 try {
340 $newSettings = $request->getSafe('updatedSettings');
341
342 $this->optionService->updateGlobalNotificationSettings($newSettings);
343
344 return $this->sendSuccess([
345 'message' => __("Notification settings are updated", 'fluent-boards'),
346 ], 201);
347 } catch (\Exception $e) {
348 return $this->sendError($e->getMessage(), 404);
349 }
350 }
351
352 public function getGlobalNotificationSettings()
353 {
354 try {
355 $globalSettings = $this->optionService->getGlobalNotificationSettings();
356 if ($globalSettings->value)
357 $currentSettings = maybe_unserialize($globalSettings->value);
358
359 return $this->sendSuccess([
360 'currentSettings' => $currentSettings,
361 ], 200);
362 } catch (\Exception $e) {
363 return $this->sendError($e->getMessage(), 404);
364 }
365 }
366
367 public function getBoardMembers(Request $request)
368 {
369 if (!PermissionManager::userHasAnyBoardAccess()) {
370 return $this->sendError([
371 'message' => __('You do not have permission to access this route', 'fluent-boards')
372 ]);
373 }
374
375 $boardId = $request->getSafe('boardId', 'intval');
376
377 $memberUserIds = Relation::where('object_type', 'board_user')
378 ->select(['foreign_id'])
379 ->groupBy('foreign_id');
380
381 if ($boardId) {
382 $memberUserIds = $memberUserIds->where('object_id', $boardId);
383 }
384
385 $members = [];
386
387 $memberUserIds = $memberUserIds->get()
388 ->pluck('foreign_id')->toArray();
389
390
391 if ($memberUserIds) {
392 $memberUsers = get_users([
393 'include' => $memberUserIds
394 ]);
395
396
397 foreach ($memberUsers as $memberUser) {
398 $name = trim($memberUser->first_name . ' ' . $memberUser->last_name);
399 if (!$name) {
400 $name = $memberUser->display_name;
401 }
402
403 $members[$memberUser->ID] = [
404 'ID' => $memberUser->ID,
405 'display_name' => $name,
406 'photo' => get_avatar_url($memberUser->user_email)
407 ];
408 }
409
410 }
411
412 $adminUsers = get_users([
413 'role' => 'administrator',
414 'exclude' => $memberUserIds
415 ]);
416
417 foreach ($adminUsers as $user) {
418 $name = trim($user->first_name . ' ' . $user->last_name);
419 if (!$name) {
420 $name = $user->display_name;
421 }
422 $members[$user->ID] = [
423 'ID' => $user->ID,
424 'display_name' => $name,
425 'photo' => get_avatar_url($user->user_email)
426 ];
427 }
428
429 $members = array_values($members);
430
431 // sort members by name
432 usort($members, function ($a, $b) {
433 return strcmp($a['display_name'], $b['display_name']);
434 });
435
436 return [
437 'members' => $members
438 ];
439 }
440
441 public function quickSearch()
442 {
443 $currentUserId = get_current_user_id();
444
445 $query = sanitize_text_field($_REQUEST['query']);
446 $query = strtolower($query);
447 $scope = sanitize_text_field($_REQUEST['scope']);
448
449 $firstThreeChars = substr($query, 0, 3);
450
451 if($firstThreeChars == 'id:') {
452 $idPart = substr($query, 3);
453 $idPart = preg_replace('/[^a-zA-Z0-9]/', '', $idPart);
454 $tasksQuery = Task::query()->where('parent_id', null)->whereRaw('id LIKE ?', ['%' . $idPart . '%']);
455 } else {
456 $tasksQuery = Task::query()->where('parent_id', null)->whereRaw('LOWER(title) LIKE ?', ['%' . $query . '%']);
457 }
458
459 $isUserAdmin = PermissionManager::isAdmin($currentUserId);
460
461 // This is a check for deleted tasks to be excluded from search results
462 $allActiveBoardsIds = Board::query()->where('archived_at', null)->pluck('id')->toArray();
463
464 if ($scope == 'all') {
465 if($firstThreeChars == 'id:'){
466 $idPart = substr($query, 3);
467 $idPart = preg_replace('/[^a-zA-Z0-9]/', '', $idPart);
468 $boardQuery = Board::query()->whereRaw('id LIKE ?', ['%' . $idPart . '%']);
469 } else {
470 $boardQuery = Board::query()->whereRaw('LOWER(title) LIKE ?', ['%' . $query . '%']);
471 }
472 if ($isUserAdmin) {
473 $boards = $boardQuery->get();
474 $tasks = $tasksQuery->get();
475 } else {
476 $boardIds = PermissionManager::getBoardIdsForUser($currentUserId);
477 $boards = $boardQuery->whereIn('id', $boardIds)->get();
478 $tasks = $tasksQuery->whereIn('board_id', $boardIds)->get();
479 }
480 } else {
481 $boards = []; // boards results is not needed in scoped search
482 $inBoard = (int)$scope;
483 if ($isUserAdmin || in_array($inBoard, $boardIds = PermissionManager::getBoardIdsForUser($currentUserId))) {
484 $tasks = $tasksQuery->where('board_id', $inBoard)->get();
485 } else {
486 // Out of permission scope search
487 $tasks = [];
488 }
489 }
490
491
492 $formattedTasks = [];
493 $formattedBoards = [];
494 foreach ($boards as $board) {
495 $formattedBoards[] = [
496 'type' => 'board',
497 'id' => $board->id,
498 'title' => $board->title,
499 'description' => $board->description,
500 'url' => Helper::getBoardUrl($board->id)
501 ];
502 }
503 foreach ($tasks as $task) {
504
505 if (!in_array($task->board_id, $allActiveBoardsIds)) {
506 // if the task is not in an active board, skip it
507 continue;
508 }
509
510 $board = $task->board;
511
512 $formattedTasks[] = [
513 'type' => 'task',
514 'id' => $task->id,
515 'title' => $task->title,
516 'description' => $task->description,
517 'url' => Helper::getTaskUrl($task->id, $board->id),
518 'board' => [
519 'id' => $board->id,
520 'title' => $board->title,
521 'url' => Helper::getBoardUrl($board->id)
522 ],
523 'stage' => [
524 'id' => $task->stage_id,
525 'title' => $task->stage->title ?? '',
526 ],
527
528 ];
529 }
530 return $this->sendSuccess([
531 'tasks' => $formattedTasks,
532 'boards' => $formattedBoards
533 ], 200);
534
535 }
536
537 public function getDashboardViewSettings()
538 {
539 try {
540 $globalSettings = $this->optionService->getDashboardViewSettings();
541 if ($globalSettings->value)
542 $currentSettings = maybe_unserialize($globalSettings->value);
543
544 return $this->sendSuccess([
545 'currentSettings' => $currentSettings,
546 ], 200);
547 } catch (\Exception $e) {
548 return $this->sendError($e->getMessage(), 404);
549 }
550 }
551
552 public function updateDashboardViewSettings(Request $request)
553 {
554 try {
555 $newSettings = $request->getSafe('updatedSettings');
556
557 $this->optionService->updateDashboardViewSettings($newSettings);
558
559 return $this->sendSuccess([
560 'message' => __("Dashboard view settings are updated", 'fluent-boards'),
561 ], 201);
562 } catch (\Exception $e) {
563 return $this->sendError($e->getMessage(), 404);
564 }
565 }
566
567
568 public function getAddonsSettings()
569 {
570 $addOns = [
571 'fluent-crm' => [
572 'title' => __('FluentCRM', 'fluent-boards'),
573 'logo' => fluent_boards_mix('images/addons/fluent-crm.svg'),
574 'is_installed' => defined('FLUENTCRM'),
575 'learn_more_url' => 'https://fluentcrm.com/',
576 'associate_doc' => 'https://fluentboards.com/docs/fluentboards-integration-with-fluentcrm/',
577 'action_text' => $this->isPluginInstalled('fluent-crm/fluent-crm.php') ? __('Activate FluentCRM', 'fluent-boards') : __('Install FluentCRM', 'fluent-boards'),
578 'description' => __('FluentCRM is a Self Hosted Email Marketing Automation Plugin for WordPress. Manage your leads and customers, email campaigns, automated email sequencing and many more', 'fluent-boards')
579 ],
580 'fluentform' => [
581 'title' => __('Fluent Forms', 'fluent-boards'),
582 'logo' => fluent_boards_mix('images/addons/fluentform.png'),
583 'is_installed' => defined('FLUENTFORM'),
584 'learn_more_url' => 'https://wordpress.org/plugins/fluentform/',
585 'associate_doc' => 'https://fluentboards.com/docs/fluentboards-integration-with-fluent-forms/',
586 'action_text' => $this->isPluginInstalled('fluent-form/fluent-form.php') ? __('Activate Fluent Forms', 'fluent-boards') : __('Install Fluent Forms', 'fluent-boards'),
587 'description' => __('Collect leads and build any type of forms, accept payments, connect with your CRM with the Fastest Contact Form Builder Plugin for WordPress', 'fluent-boards')
588 ],
589 'fluent-support' => [
590 'title' => __('Fluent Support', 'fluent-boards'),
591 'logo' => fluent_boards_mix('images/addons/fluent-support.svg'),
592 'is_installed' => defined('FLUENT_SUPPORT_VERSION'),
593 'learn_more_url' => 'https://wordpress.org/plugins/fluent-connect/',
594 'settings_url' => admin_url('admin.php?page=fluent-support#/'),
595 'associate_doc' => 'https://fluentboards.com/docs/fluentboards-integration-with-fluentsupport/',
596 'action_text' => $this->isPluginInstalled('fluent-support/fluent-support.php') ? __('Activate Fluent Support', 'fluent-boards') : __('Install Fluent Support', 'fluent-boards'),
597 'description' => __('WordPress Helpdesk and Customer Support Ticket Plugin. Provide awesome support and manage customer queries right from your WordPress dashboard.', 'fluent-boards')
598 ],
599 'fluent-smtp' => [
600 'title' => __('Fluent SMTP', 'fluent-boards'),
601 'logo' => fluent_boards_mix('images/addons/fluent-smtp.svg'),
602 'is_installed' => defined('FLUENTMAIL'),
603 'learn_more_url' => 'https://wordpress.org/plugins/fluent-smtp/',
604 'associate_doc' => admin_url('options-general.php?page=fluent-mail#/'),
605 'action_text' => $this->isPluginInstalled('fluent-smtp/fluent-smtp.php') ? __('Activate Fluent SMTP', 'fluent-boards') : __('Install Fluent SMTP', 'fluent-boards'),
606 'description' => __('The Ultimate SMTP and SES Plugin for WordPress. Connect with any SMTP, SendGrid, Mailgun, SES, Sendinblue, PepiPost, Google, Microsoft and more.', 'fluent-boards')
607 ],
608 ];
609
610 $addOns = apply_filters('fluent_boards/addons_settings', $addOns);
611
612 $modules = fluent_boards_get_pref_settings(false);
613
614 if (empty($modules['frontend']['render_type'])) {
615 $modules['frontend']['render_type'] = 'standalone';
616 }
617
618 $modules['panel_url'] = fluent_boards_page_url();
619
620 return [
621 'addons' => $addOns,
622 'featureModules' => $modules
623 ];
624 }
625
626 public function saveAddonsSettings(Request $request)
627 {
628 if (!defined('FLUENT_BOARDS_PRO')) {
629 return $this->sendError([
630 'message' => __('This feature is only available in Fluent Boards Pro', 'fluent-boards')
631 ]);
632 }
633
634 $settings = $request->get('settings', []);
635
636 $prefSettings = fluent_boards_get_pref_settings(false);
637
638 $settings = wp_parse_args($settings, $prefSettings);
639
640 $settings = Arr::only($settings, array_keys($prefSettings));
641 $settings['frontend']['slug'] = sanitize_title($settings['frontend']['slug']);
642
643 if (empty($settings['frontend']['slug'])) {
644 $settings['frontend']['slug'] = 'projects';
645 }
646
647 if (defined('FLUENT_BOARDS_SLUG') && FLUENT_BOARDS_SLUG) {
648 $settings['frontend']['slug'] = FLUENT_BOARDS_SLUG;
649 }
650
651 do_action('fluent_boards/saving_addons', $settings, $prefSettings);
652
653 update_option('fluent_boards_modules', $settings, 'yes');
654
655 return $this->sendSuccess([
656 'message' => __('Settings are saved', 'fluent-boards'),
657 'featureModules' => $settings
658 ]);
659 }
660
661 public function installPlugin(Request $request)
662 {
663 if (!current_user_can('install_plugins')) {
664 return $this->sendError([
665 'message' => __('Sorry! you do not have permission to install plugin', 'fluent-crm')
666 ]);
667 }
668
669 $plugin = $request->getSafe('plugin', 'sanitize_text_field');
670
671 $acceptedFreePlugins = [
672 'fluent-crm' => 'fluent-crm.php',
673 'fluentform' => 'fluentform.php',
674 'fluent-support' => 'fluent-support.php',
675 'fluent-smtp' => 'fluent-smtp.php'
676 ];
677
678 $acceptedPlugins = apply_filters('fluent_boards/accepted_plugins', $acceptedFreePlugins);
679
680 if (!isset($acceptedPlugins[$plugin])) {
681 return $this->sendError([
682 'message' => __('Invalid plugin', 'fluent-boards')
683 ]);
684 }
685
686 $pluginToInstall = [
687 'name' => __('Fluent Plugin', 'fluent-boards'),
688 'repo-slug' => $plugin,
689 'file' => $acceptedPlugins[$plugin],
690 ];
691
692 // if plugin in free list then run background intaller otherwise call an action to install
693 if (isset($acceptedFreePlugins[$plugin])) {
694 $this->backgroundInstaller($pluginToInstall, $plugin);
695 } else {
696 do_action('fluent_boards/install_plugin', $pluginToInstall, $plugin);
697 }
698
699 return $this->sendSuccess([
700 'message' => __('Plugin is being installed', 'fluent-boards')
701 ]);
702 }
703
704 private function isPluginInstalled($plugin)
705 {
706 return file_exists(WP_PLUGIN_DIR . '/' . $plugin);
707 }
708
709 private function backgroundInstaller($plugin_to_install, $plugin_id)
710 {
711 if (!empty($plugin_to_install['repo-slug'])) {
712 require_once ABSPATH . 'wp-admin/includes/file.php';
713 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
714 require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
715 require_once ABSPATH . 'wp-admin/includes/plugin.php';
716
717 WP_Filesystem();
718
719 $skin = new \Automatic_Upgrader_Skin();
720 $upgrader = new \WP_Upgrader($skin);
721 $installed_plugins = array_reduce(array_keys(\get_plugins()), array($this, 'associate_plugin_file'), array());
722 $plugin_slug = $plugin_to_install['repo-slug'];
723 $plugin_file = isset($plugin_to_install['file']) ? $plugin_to_install['file'] : $plugin_slug . '.php';
724 $installed = false;
725 $activate = false;
726
727 // See if the plugin is installed already.
728 if (isset($installed_plugins[$plugin_file])) {
729 $installed = true;
730 $activate = !is_plugin_active($installed_plugins[$plugin_file]);
731 }
732
733 // Install this thing!
734 if (!$installed) {
735 // Suppress feedback.
736 ob_start();
737
738 try {
739 $plugin_information = plugins_api(
740 'plugin_information',
741 array(
742 'slug' => $plugin_slug,
743 'fields' => array(
744 'short_description' => false,
745 'sections' => false,
746 'requires' => false,
747 'rating' => false,
748 'ratings' => false,
749 'downloaded' => false,
750 'last_updated' => false,
751 'added' => false,
752 'tags' => false,
753 'homepage' => false,
754 'donate_link' => false,
755 'author_profile' => false,
756 'author' => false,
757 ),
758 )
759 );
760
761 if (is_wp_error($plugin_information)) {
762 throw new \Exception($plugin_information->get_error_message());
763 }
764
765 $package = $plugin_information->download_link;
766 $download = $upgrader->download_package($package);
767
768 if (is_wp_error($download)) {
769 throw new \Exception($download->get_error_message());
770 }
771
772 $working_dir = $upgrader->unpack_package($download, true);
773
774 if (is_wp_error($working_dir)) {
775 throw new \Exception($working_dir->get_error_message());
776 }
777
778 $result = $upgrader->install_package(
779 array(
780 'source' => $working_dir,
781 'destination' => WP_PLUGIN_DIR,
782 'clear_destination' => false,
783 'abort_if_destination_exists' => false,
784 'clear_working' => true,
785 'hook_extra' => array(
786 'type' => 'plugin',
787 'action' => 'install',
788 ),
789 )
790 );
791
792 if (is_wp_error($result)) {
793 throw new \Exception($result->get_error_message());
794 }
795
796 $activate = true;
797
798 } catch (\Exception $e) {
799 }
800
801 // Discard feedback.
802 ob_end_clean();
803 }
804
805 wp_clean_plugins_cache();
806
807 // Activate this thing.
808 if ($activate) {
809 try {
810 $result = activate_plugin($installed ? $installed_plugins[$plugin_file] : $plugin_slug . '/' . $plugin_file);
811
812 if (is_wp_error($result)) {
813 throw new \Exception($result->get_error_message());
814 }
815 } catch (\Exception $e) {
816 }
817 }
818 }
819 }
820
821 private function associate_plugin_file($plugins, $key)
822 {
823 $path = explode('/', $key);
824 $filename = end($path);
825 $plugins[$filename] = $key;
826 return $plugins;
827 }
828
829 public function getBoards(Request $request)
830 {
831 $boards = Board::select(['id', 'title', 'type'])
832 ->byAccessUser(get_current_user_id())
833 ->orderBy('title', 'ASC')
834 ->get();
835
836 return $this->sendSuccess([
837 'boards' => $boards
838 ]);
839 }
840
841 public function getPages(Request $request)
842 {
843
844 $db = App::getInstance('db');
845
846 $allPages = $db->table('posts')->where('post_type', 'page')
847 ->where('post_status', 'publish')
848 ->select(['ID', 'post_title'])
849 ->orderBy('post_title', 'ASC')
850 ->get();
851
852 $pages = [];
853 foreach ($allPages as $page) {
854 $pages[] = [
855 'id' => $page->ID,
856 'title' => $page->post_title ? $page->post_title : __('(no title)', 'fluent-boards')
857 ];
858 }
859
860 return $this->sendSuccess([
861 'pages' => $pages
862 ]);
863 }
864
865 public function getGeneralSettings()
866 {
867 $settings = fluent_boards_get_option('general_settings', []);
868
869 return $this->sendSuccess([
870 'settings' => $settings,
871 'server_timezone' => \wp_timezone_string()
872 ]);
873
874 }
875
876 public function saveGeneralSettings(Request $request)
877 {
878 // check for pro version
879 if (!defined('FLUENT_BOARDS_PRO')) {
880 return $this->sendError([
881 'message' => __('This feature is only available in Fluent Boards Pro. Please upgrade.', 'fluent-boards')
882 ]);
883 }
884 $settings = $request->getSafe('updatedSettings', []);
885
886 $settings = apply_filters('fluent_boards/save_general_settings', $settings);
887
888 $savedSettings = fluent_boards_update_option('general_settings', $settings);
889 $savedGeneralSettings = \maybe_unserialize($savedSettings->value);
890
891 $scheduleHandler = new ProScheduleHandler();
892
893 if ($savedGeneralSettings['daily_reminder_enabled'] || $savedGeneralSettings['daily_reminder_enabled'] == 'true') {
894 // force schedule from this settings update
895 $scheduleHandler->clearSchedule();
896 $scheduleHandler->schedule();
897 }
898
899 return $this->sendSuccess([
900 'settings' => $savedGeneralSettings,
901 'message' => __('Settings are saved', 'fluent-boards')
902 ]);
903
904 }
905
906 }
907