PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.0.10
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.0.10
2.1.0 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 All 42 releases
fluent-boards / app / Hooks / actions.php

actions.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.0.10, at app/Hooks/actions.php

243 lines 13.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 //if accessed directly exit
3 if (!defined('ABSPATH')) exit;
4
5 use FluentBoards\App\Services\Helper;
6
7 /**
8 * All registered action's handlers should be in app\Hooks\Handlers,
9 * addAction is similar to add_action and addCustomAction is just a
10 * wrapper over add_action which will add a prefix to the hook name
11 * using the plugin slug to make it unique in all WordPress plugins,
12 * ex: $app->addCustomAction('foo', ['FooHandler', 'handleFoo']) is
13 * equivalent to add_action('slug-foo', ['FooHandler', 'handleFoo']).
14 */
15
16 /**
17 * @var $app FluentBoards\Framework\Foundation\Application
18 */
19
20 (new \FluentBoards\App\Hooks\Handlers\AdminMenuHandler())->register();
21
22 /*
23 * Add custom CSS for fbs_notice.
24 */
25 add_action('admin_head', function () {
26 echo '<style>
27 .fbs_notice {
28 background: var(--fbs-primary-bg, #ffffff);
29 border: 1px solid var(--fbs-primary-border, #E1E4EA);
30 border-left: 3px solid #FB3748;
31 padding: 10px 12px !important;
32 border-radius: 8px;
33 margin-bottom: 5px;
34 }
35 </style>';
36 });
37
38 //$app->addCustomAction('task_prop_changed', 'ActivityHandler@logActivity', 10, 3);
39 $app->addCustomAction('task_board_changed', 'ActivityHandler@logMoveTaskToAnotherBoardActivity', 10, 2); //will call from service after board change code merged
40 $app->addCustomAction('task_due_date_changed', 'ActivityHandler@logDueDateActivity', 10, 2);
41 $app->addCustomAction('task_due_date_removed', 'ActivityHandler@logDueDateRemoveActivity', 10, 1);
42 $app->addCustomAction('task_start_date_changed', 'ActivityHandler@logStartDateActivity', 10, 2);
43
44 $app->addCustomAction('task_priority_changed', 'ActivityHandler@logPriorityChangeActivity', 10, 2);
45 $app->addCustomAction('comment_created', 'ActivityHandler@logCommentCreateActivity', 10, 1);
46 $app->addCustomAction('comment_updated', 'ActivityHandler@logCommentUpdateActivity', 10, 2);
47 $app->addCustomAction('comment_deleted', 'ActivityHandler@logCommentDeleteActivity', 10, 1);
48 $app->addCustomAction('subtask_added', 'ActivityHandler@logSubtaskAddedActivity', 10, 2);
49 $app->addCustomAction('subtask_cloned', 'ActivityHandler@logSubtaskCloneActivity', 10, 2);
50 $app->addCustomAction('subtask_group_created', 'ActivityHandler@logSubtaskGroupAddedActivity', 10, 2);
51 $app->addCustomAction('subtask_deleted_activity', 'ActivityHandler@logSubtaskDeletedActivity', 10, 2);
52 $app->addCustomAction('subtask_group_deleted_activity', 'ActivityHandler@logSubtaskGroupDeletedActivity', 10, 2);
53 $app->addCustomAction('subtask_group_title_updated', 'ActivityHandler@logSubtaskGroupTitleUpdatedActivity', 10, 2);
54 $app->addCustomAction('task_completed_activity', 'ActivityHandler@logTaskCompletedOrReopenActivity', 10, 2);
55 $app->addCustomAction('task_stage_updated', 'ActivityHandler@logTaskStageUpdatedActivity', 10, 2);
56 $app->addCustomAction('task_assignee_added', 'ActivityHandler@logAssigneeAddedActivity', 10, 2);
57 $app->addCustomAction('task_assignee_removed', 'ActivityHandler@logAssigneeRemovedActivity', 10, 2);
58 $app->addCustomAction('task_added_from_fluent_form', 'ActivityHandler@taskAddedFromFluentForms', 10, 1);
59 $app->addCustomAction('repeat_task_created', 'ActivityHandler@logRepeatTaskCreatedActivity', 10, 2);
60 $app->addCustomAction('repeat_task_set', 'ActivityHandler@logRepeatTaskSet', 10, 1);
61 $app->addCustomAction('repeat_task_updated', 'ActivityHandler@logRepeatTaskUpdated', 10, 1);
62 $app->addCustomAction('task_created', 'ActivityHandler@logTaskCreationActivity', 10, 1);
63 $app->addCustomAction('task_content_updated', 'ActivityHandler@logTaskContentUpdatedActivity', 10, 3);
64 $app->addCustomAction('task_deleted', 'TaskHandler@taskDeleted', 10, 1);
65 $app->addCustomAction('task_archived', 'ActivityHandler@taskArchived', 10, 1);
66 //$app->addCustomAction('task_custom_field_changed', 'ActivityHandler@logCustomFieldActivity', 10, 5); // commented for now, will implement later
67
68 $app->addCustomAction('board_created', 'BoardHandler@boardCreated', 10, 1);
69 $app->addCustomAction('board_created_from_automation', 'BoardHandler@boardCreatedFromAutomation', 10, 1);
70 $app->addCustomAction('before_board_deleted', 'BoardHandler@beforeBoardDeleted', 10, 2);
71 $app->addCustomAction('board_updated', 'BoardHandler@boardUpdated', 10, 2);
72 $app->addCustomAction('stage_updated', 'BoardHandler@boardStageUpdated', 10, 3);
73 $app->addCustomAction('board_stage_moved', 'BoardHandler@boardStageMoved', 10, 2);
74 $app->addCustomAction('board_stage_added', 'BoardHandler@boardStageAdded', 10, 2);
75 $app->addCustomAction('stage_deleted', 'BoardHandler@boardStageDeleted', 10, 2);
76 $app->addCustomAction('stage_archived', 'BoardHandler@boardStageArchived', 10, 2);
77 $app->addCustomAction('board_stage_restored', 'BoardHandler@boardArchivedStageRestore', 10, 2);
78 $app->addCustomAction('task_created', 'BoardHandler@taskCreatedOnBoard', 10, 1);
79 $app->addCustomAction('before_task_deleted', 'BoardHandler@beforeTaskDeleted', 10, 2);
80 $app->addCustomAction('task_deleted', 'BoardHandler@taskdeleted', 10, 1);
81 $app->addCustomAction('task_moved_from_board', 'BoardHandler@taskMovedFromBoard', 10, 3);
82 $app->addCustomAction('task_moved_from_board', 'ActivityHandler@taskMovedFromBoard', 10, 3);
83 $app->addCustomAction('task_archived', 'BoardHandler@taskArchivedOnBoard', 10, 1);
84 $app->addCustomAction('board_member_added', 'BoardHandler@boardMemberAdded', 10, 2);
85 $app->addCustomAction('board_viewer_added', 'BoardHandler@boardViewerAdded', 10, 2);
86 $app->addCustomAction('board_member_removed', 'BoardHandler@boardMemberRemoved', 10, 2);
87 $app->addCustomAction('board_admin_added', 'BoardHandler@boardAdminAdded', 10, 2);
88 $app->addCustomAction('board_admin_removed', 'BoardHandler@boardAdminRemoved', 10, 2);
89 $app->addCustomAction('associate_user_add_change_remove_activity', 'ActivityHandler@associateUserAddChangeRemoveActivity', 10, 3);
90 $app->addCustomAction('task_assignee_leave', 'ActivityHandler@taskAssigneeLeave', 10, 1);
91 $app->addCustomAction('task_assignee_join', 'ActivityHandler@taskAssigneeJoin', 10, 1);
92 $app->addCustomAction('task_label', 'ActivityHandler@taskLabelActivity', 10, 3);
93 $app->addCustomAction('label_manage_for_task_activity', 'ActivityHandler@labelManageForTaskActivity', 10, 2);
94 $app->addCustomAction('board_label_created', 'BoardHandler@boardLabelCreatedActivity', 10, 1);
95 $app->addCustomAction('board_label_updated', 'BoardHandler@boardLabelUpdatedActivity', 10, 1);
96 $app->addCustomAction('board_label_deleted', 'BoardHandler@boardLabelDeletedActivity', 10, 1);
97 $app->addCustomAction('board_stages_reordered', 'BoardHandler@boardStagesReOrdered', 10, 2);
98 $app->addCustomAction('default_assignees_updated', 'BoardHandler@defaultAssigneesUpdated', 10, 2);
99
100 $app->addCustomAction('comment_created', 'NotificationHandler@addCommentNotification', 10, 1);
101 $app->addCustomAction('mention_comment_notification', 'NotificationHandler@mentionInCommentNotification', 10, 2);
102 $app->addCustomAction('subtask_added', 'NotificationHandler@addSubtaskNotification', 10, 2);
103 $app->addCustomAction('task_due_date_changed', 'NotificationHandler@changeDueDateNotification', 10, 2);
104 $app->addCustomAction('task_start_date_changed', 'NotificationHandler@changeStartDateNotification', 10, 2);
105 $app->addCustomAction('task_stage_updated', 'NotificationHandler@changeStageNotification', 10, 2);
106 $app->addCustomAction('task_priority_changed', 'NotificationHandler@changePriorityNotification', 10, 2);
107 $app->addCustomAction('task_archived', 'NotificationHandler@taskArchiveNotification', 10, 1);
108 $app->addCustomAction('task_content_updated', 'NotificationHandler@changeTitleNotification', 10, 3);
109 //$app->addCustomAction('description_changed_notification', 'NotificationHandler@changeDescriptionNotification', 10, 1);
110 $app->addCustomAction('board_changed_notification', 'NotificationHandler@changeBoardNotification', 10, 2);
111 $app->addCustomAction('task_assignee_added', 'NotificationHandler@assigneeAddedNotification', 10, 2);
112 $app->addCustomAction('task_assignee_removed', 'NotificationHandler@assigneeRemovedNotification', 10, 2);
113
114 $app->addCustomAction('one_time_schedule_send_email_for_comment', 'ScheduleHandler@sendEmailForComment', 10, 3);
115 $app->addCustomAction('one_time_schedule_send_email_for_mention', 'ScheduleHandler@sendEmailForMention', 10, 3);
116 $app->addCustomAction('one_time_schedule_send_email_for_add_assignee', 'ScheduleHandler@sendEmailForAddAssignee', 10, 3);
117 $app->addCustomAction('one_time_schedule_send_email_for_remove_assignee', 'ScheduleHandler@sendEmailForRemoveAssignee', 10, 3);
118 $app->addCustomAction('one_time_schedule_send_email_for_stage_change', 'ScheduleHandler@sendEmailForChangeStage', 10, 3);
119
120 //Todo:: update handler
121 $app->addCustomAction('one_time_schedule_send_email_for_due_date_update', 'ScheduleHandler@sendEmailForDueDateUpdate', 10, 3);
122 $app->addCustomAction('one_time_schedule_send_email_for_task_archived', 'ScheduleHandler@sendEmailForArchivedTask', 10, 3);
123 $app->addCustomAction('one_time_schedule_send_email_for_removed_from_task', 'ScheduleHandler@sendEmailForChangeStage', 10, 3);
124
125 $app->addCustomAction('task_attachment_added', 'ActivityHandler@taskAttachmentAdded', 10, 1);
126 $app->addCustomAction('task_attachment_deleted', 'ActivityHandler@taskAttachmentDeleted', 10, 1);
127 $app->addCustomAction('task_attachment_deleted', 'TaskHandler@taskAttachmentDeleted', 10, 1);
128 // Removed: direct call is made from Comment::deleting to TaskHandler@commentImageDeleted
129 $app->addAction('deleted_user', 'BoardHandler@deleteUserRelatedData', 10, 3);
130
131 $app->addCustomAction('task_created', 'TaskHandler@onTaskCreated', 10, 1);
132 $app->addCustomAction('comment_created', 'TaskHandler@onCommentCreated', 10, 1);
133 $app->addCustomAction('assign_another_user', 'TaskHandler@onAssignAnotherUser', 10, 2);
134 $app->addCustomAction('board_background_updated', 'BoardHandler@backgroundUpdated', 10, 2);
135 $app->addCustomAction('task_cloned', 'TaskHandler@taskCloned', 10, 2);
136 $app->addCustomAction('task_cloned_activity', 'ActivityHandler@taskCloned', 10, 2);
137
138 if (defined('WP_CLI') && WP_CLI) {
139 \WP_CLI::add_command('fluent_boards', '\FluentBoards\App\Hooks\Cli\Commands');
140 }
141
142
143 add_action('init', function () {
144 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing parameter check, no data modification
145 if (!isset($_REQUEST['fbs'])) {
146 return;
147 }
148 });
149
150 /*
151 * IMPORTANT
152 * External Pages Handler
153 * Each Request must have fbs=1 as a query parameter, then the plugin will handle the request.
154 */
155 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing logic, security validated in individual handlers
156 if(isset($_GET['fbs']) && $_GET['fbs'] == 1) {
157
158 // For viewing attachment
159 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing logic, security validated in handler
160 if(isset($_GET['route']) && ($_GET['route'] == 'task')) {
161 add_action('init', function() {
162 (new \FluentBoardsPro\App\Hooks\Handlers\ExternalPages())->handleTaskWebhook();
163 });
164 }
165
166 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public file serving endpoint, security validated by hash in handler
167 if(isset($_GET['fbs_comment_image'])) {
168 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing check, security validated in handler
169 if(isset($_GET['fbs_type']) && $_GET['fbs_type'] == 'public_url') {
170 add_action('init', function() {
171 (new \FluentBoards\App\Hooks\Handlers\ExternalPages())->view_uploaded_comment_image();
172 });
173 } else {
174 add_action('init', function() {
175 (new \FluentBoards\App\Hooks\Handlers\ExternalPages())->view_comment_image();
176 });
177 }
178
179 }
180
181 }
182
183 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public redirect endpoint, no sensitive operations
184 if(isset($_GET['redirect']) && $_GET['redirect'] == 'to_task') {
185 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public redirect endpoint, validation performed in handler
186 if (isset($_GET['taskId'])) {
187 add_action('init', function() {
188 (new \FluentBoards\App\Hooks\Handlers\ExternalPages())->redirectToPage();
189 });
190 }
191 }
192 // Stage Archive Handler - Archive tasks when stage is archived, restore when stage is restored
193 $app->addAction('fluent_boards/stage_archived_with_tasks', 'StageArchiveHandler@onStageArchived', 10, 2);
194 $app->addAction('fluent_boards/stage_restored_with_tasks', 'StageArchiveHandler@onStageRestored', 10, 2);
195
196 /*
197 * MCP - Register Fluent Boards abilities for the WordPress Abilities API.
198 *
199 * This mirrors FluentCRM's MCP architecture: on WordPress installs without the
200 * Abilities API / WP MCP Adapter, `wp_register_ability` is undefined and the
201 * integration skips silently. Admins can opt out with the `mcp_enabled` option.
202 */
203 add_filter('fluent_kit/mcp_products', [\FluentBoards\App\Modules\MCP\MCPInit::class, 'registerToolkitProduct'], 10, 2);
204 add_filter('fluent_kit/mcp_toggle_handlers', function ($handlers) {
205 $handlers['fluent-boards'] = [
206 'get_enabled' => function () {
207 return fluent_boards_get_option('mcp_enabled', 'yes') === 'yes';
208 },
209 'set_enabled' => function ($enabled) {
210 fluent_boards_update_option('mcp_enabled', $enabled ? 'yes' : 'no');
211 },
212 ];
213
214 return $handlers;
215 });
216
217 add_action('init', function () {
218 if (!function_exists('wp_register_ability')) {
219 return;
220 }
221
222 if (fluent_boards_get_option('mcp_enabled', 'yes') !== 'yes') {
223 return;
224 }
225
226 (new \FluentBoards\App\Modules\MCP\MCPInit())->init();
227 }, 5);
228
229 $invalidateMcpContext = [\FluentBoards\App\Modules\MCP\Tools\ContextTools::class, 'invalidateCache'];
230 foreach ([
231 'fluent_boards/board_created',
232 'fluent_boards/board_updated',
233 'fluent_boards/before_board_deleted',
234 'fluent_boards/board_stage_added',
235 'fluent_boards/stage_updated',
236 'fluent_boards/stage_deleted',
237 'fluent_boards/board_label_created',
238 'fluent_boards/board_label_updated',
239 'fluent_boards/board_label_deleted',
240 ] as $mcpContextHook) {
241 add_action($mcpContextHook, $invalidateMcpContext);
242 }
243