PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.95.2
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.95.2
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 1.95.2, at app/Hooks/actions.php

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