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

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

242 lines 13.8 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('before_board_deleted', 'BoardHandler@beforeBoardDeleted', 10, 2);
70 $app->addCustomAction('board_updated', 'BoardHandler@boardUpdated', 10, 2);
71 $app->addCustomAction('stage_updated', 'BoardHandler@boardStageUpdated', 10, 3);
72 $app->addCustomAction('board_stage_moved', 'BoardHandler@boardStageMoved', 10, 2);
73 $app->addCustomAction('board_stage_added', 'BoardHandler@boardStageAdded', 10, 2);
74 $app->addCustomAction('stage_deleted', 'BoardHandler@boardStageDeleted', 10, 2);
75 $app->addCustomAction('stage_archived', 'BoardHandler@boardStageArchived', 10, 2);
76 $app->addCustomAction('board_stage_restored', 'BoardHandler@boardArchivedStageRestore', 10, 2);
77 $app->addCustomAction('task_created', 'BoardHandler@taskCreatedOnBoard', 10, 1);
78 $app->addCustomAction('before_task_deleted', 'BoardHandler@beforeTaskDeleted', 10, 2);
79 $app->addCustomAction('task_deleted', 'BoardHandler@taskdeleted', 10, 1);
80 $app->addCustomAction('task_moved_from_board', 'BoardHandler@taskMovedFromBoard', 10, 3);
81 $app->addCustomAction('task_moved_from_board', 'ActivityHandler@taskMovedFromBoard', 10, 3);
82 $app->addCustomAction('task_archived', 'BoardHandler@taskArchivedOnBoard', 10, 1);
83 $app->addCustomAction('board_member_added', 'BoardHandler@boardMemberAdded', 10, 2);
84 $app->addCustomAction('board_viewer_added', 'BoardHandler@boardViewerAdded', 10, 2);
85 $app->addCustomAction('board_member_removed', 'BoardHandler@boardMemberRemoved', 10, 2);
86 $app->addCustomAction('board_admin_added', 'BoardHandler@boardAdminAdded', 10, 2);
87 $app->addCustomAction('board_admin_removed', 'BoardHandler@boardAdminRemoved', 10, 2);
88 $app->addCustomAction('associate_user_add_change_remove_activity', 'ActivityHandler@associateUserAddChangeRemoveActivity', 10, 3);
89 $app->addCustomAction('task_assignee_leave', 'ActivityHandler@taskAssigneeLeave', 10, 1);
90 $app->addCustomAction('task_assignee_join', 'ActivityHandler@taskAssigneeJoin', 10, 1);
91 $app->addCustomAction('task_label', 'ActivityHandler@taskLabelActivity', 10, 3);
92 $app->addCustomAction('label_manage_for_task_activity', 'ActivityHandler@labelManageForTaskActivity', 10, 2);
93 $app->addCustomAction('board_label_created', 'BoardHandler@boardLabelCreatedActivity', 10, 1);
94 $app->addCustomAction('board_label_updated', 'BoardHandler@boardLabelUpdatedActivity', 10, 1);
95 $app->addCustomAction('board_label_deleted', 'BoardHandler@boardLabelDeletedActivity', 10, 1);
96 $app->addCustomAction('board_stages_reordered', 'BoardHandler@boardStagesReOrdered', 10, 2);
97 $app->addCustomAction('default_assignees_updated', 'BoardHandler@defaultAssigneesUpdated', 10, 2);
98
99 $app->addCustomAction('comment_created', 'NotificationHandler@addCommentNotification', 10, 1);
100 $app->addCustomAction('mention_comment_notification', 'NotificationHandler@mentionInCommentNotification', 10, 2);
101 $app->addCustomAction('subtask_added', 'NotificationHandler@addSubtaskNotification', 10, 2);
102 $app->addCustomAction('task_due_date_changed', 'NotificationHandler@changeDueDateNotification', 10, 2);
103 $app->addCustomAction('task_start_date_changed', 'NotificationHandler@changeStartDateNotification', 10, 2);
104 $app->addCustomAction('task_stage_updated', 'NotificationHandler@changeStageNotification', 10, 2);
105 $app->addCustomAction('task_priority_changed', 'NotificationHandler@changePriorityNotification', 10, 2);
106 $app->addCustomAction('task_archived', 'NotificationHandler@taskArchiveNotification', 10, 1);
107 $app->addCustomAction('task_content_updated', 'NotificationHandler@changeTitleOrDescriptionNotification', 10, 3);
108 //$app->addCustomAction('description_changed_notification', 'NotificationHandler@changeDescriptionNotification', 10, 1);
109 $app->addCustomAction('board_changed_notification', 'NotificationHandler@changeBoardNotification', 10, 2);
110 $app->addCustomAction('task_assignee_added', 'NotificationHandler@assigneeAddedNotification', 10, 2);
111 $app->addCustomAction('task_assignee_removed', 'NotificationHandler@assigneeRemovedNotification', 10, 2);
112
113 $app->addCustomAction('one_time_schedule_send_email_for_comment', 'ScheduleHandler@sendEmailForComment', 10, 3);
114 $app->addCustomAction('one_time_schedule_send_email_for_mention', 'ScheduleHandler@sendEmailForMention', 10, 3);
115 $app->addCustomAction('one_time_schedule_send_email_for_add_assignee', 'ScheduleHandler@sendEmailForAddAssignee', 10, 3);
116 $app->addCustomAction('one_time_schedule_send_email_for_remove_assignee', 'ScheduleHandler@sendEmailForRemoveAssignee', 10, 3);
117 $app->addCustomAction('one_time_schedule_send_email_for_stage_change', 'ScheduleHandler@sendEmailForChangeStage', 10, 3);
118
119 //Todo:: update handler
120 $app->addCustomAction('one_time_schedule_send_email_for_due_date_update', 'ScheduleHandler@sendEmailForDueDateUpdate', 10, 3);
121 $app->addCustomAction('one_time_schedule_send_email_for_task_archived', 'ScheduleHandler@sendEmailForArchivedTask', 10, 3);
122 $app->addCustomAction('one_time_schedule_send_email_for_removed_from_task', 'ScheduleHandler@sendEmailForChangeStage', 10, 3);
123
124 $app->addCustomAction('task_attachment_added', 'ActivityHandler@taskAttachmentAdded', 10, 1);
125 $app->addCustomAction('task_attachment_deleted', 'ActivityHandler@taskAttachmentDeleted', 10, 1);
126 $app->addCustomAction('task_attachment_deleted', 'TaskHandler@taskAttachmentDeleted', 10, 1);
127 // Removed: direct call is made from Comment::deleting to TaskHandler@commentImageDeleted
128 $app->addAction('deleted_user', 'BoardHandler@deleteUserRelatedData', 10, 3);
129
130 $app->addCustomAction('task_created', 'TaskHandler@onTaskCreated', 10, 1);
131 $app->addCustomAction('comment_created', 'TaskHandler@onCommentCreated', 10, 1);
132 $app->addCustomAction('assign_another_user', 'TaskHandler@onAssignAnotherUser', 10, 2);
133 $app->addCustomAction('board_background_updated', 'BoardHandler@backgroundUpdated', 10, 2);
134 $app->addCustomAction('task_cloned', 'TaskHandler@taskCloned', 10, 2);
135 $app->addCustomAction('task_cloned_activity', 'ActivityHandler@taskCloned', 10, 2);
136
137 if (defined('WP_CLI') && WP_CLI) {
138 \WP_CLI::add_command('fluent_boards', '\FluentBoards\App\Hooks\Cli\Commands');
139 }
140
141
142 add_action('init', function () {
143 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing parameter check, no data modification
144 if (!isset($_REQUEST['fbs'])) {
145 return;
146 }
147 });
148
149 /*
150 * IMPORTANT
151 * External Pages Handler
152 * Each Request must have fbs=1 as a query parameter, then the plugin will handle the request.
153 */
154 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing logic, security validated in individual handlers
155 if(isset($_GET['fbs']) && $_GET['fbs'] == 1) {
156
157 // For viewing attachment
158 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing logic, security validated in handler
159 if(isset($_GET['route']) && ($_GET['route'] == 'task')) {
160 add_action('init', function() {
161 (new \FluentBoardsPro\App\Hooks\Handlers\ExternalPages())->handleTaskWebhook();
162 });
163 }
164
165 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public file serving endpoint, security validated by hash in handler
166 if(isset($_GET['fbs_comment_image'])) {
167 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public routing check, security validated in handler
168 if(isset($_GET['fbs_type']) && $_GET['fbs_type'] == 'public_url') {
169 add_action('init', function() {
170 (new \FluentBoards\App\Hooks\Handlers\ExternalPages())->view_uploaded_comment_image();
171 });
172 } else {
173 add_action('init', function() {
174 (new \FluentBoards\App\Hooks\Handlers\ExternalPages())->view_comment_image();
175 });
176 }
177
178 }
179
180 }
181
182 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public redirect endpoint, no sensitive operations
183 if(isset($_GET['redirect']) && $_GET['redirect'] == 'to_task') {
184 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public redirect endpoint, validation performed in handler
185 if (isset($_GET['taskId'])) {
186 add_action('init', function() {
187 (new \FluentBoards\App\Hooks\Handlers\ExternalPages())->redirectToPage();
188 });
189 }
190 }
191 // Stage Archive Handler - Archive tasks when stage is archived, restore when stage is restored
192 $app->addAction('fluent_boards/stage_archived_with_tasks', 'StageArchiveHandler@onStageArchived', 10, 2);
193 $app->addAction('fluent_boards/stage_restored_with_tasks', 'StageArchiveHandler@onStageRestored', 10, 2);
194
195 /*
196 * MCP - Register Fluent Boards abilities for the WordPress Abilities API.
197 *
198 * This mirrors FluentCRM's MCP architecture: on WordPress installs without the
199 * Abilities API / WP MCP Adapter, `wp_register_ability` is undefined and the
200 * integration skips silently. Admins can opt out with the `mcp_enabled` option.
201 */
202 add_filter('fluent_kit/mcp_products', [\FluentBoards\App\Modules\MCP\MCPInit::class, 'registerToolkitProduct'], 10, 2);
203 add_filter('fluent_kit/mcp_toggle_handlers', function ($handlers) {
204 $handlers['fluent-boards'] = [
205 'get_enabled' => function () {
206 return fluent_boards_get_option('mcp_enabled', 'yes') === 'yes';
207 },
208 'set_enabled' => function ($enabled) {
209 fluent_boards_update_option('mcp_enabled', $enabled ? 'yes' : 'no');
210 },
211 ];
212
213 return $handlers;
214 });
215
216 add_action('init', function () {
217 if (!function_exists('wp_register_ability')) {
218 return;
219 }
220
221 if (fluent_boards_get_option('mcp_enabled', 'yes') !== 'yes') {
222 return;
223 }
224
225 (new \FluentBoards\App\Modules\MCP\MCPInit())->init();
226 }, 5);
227
228 $invalidateMcpContext = [\FluentBoards\App\Modules\MCP\Tools\ContextTools::class, 'invalidateCache'];
229 foreach ([
230 'fluent_boards/board_created',
231 'fluent_boards/board_updated',
232 'fluent_boards/before_board_deleted',
233 'fluent_boards/board_stage_added',
234 'fluent_boards/stage_updated',
235 'fluent_boards/stage_deleted',
236 'fluent_boards/board_label_created',
237 'fluent_boards/board_label_updated',
238 'fluent_boards/board_label_deleted',
239 ] as $mcpContextHook) {
240 add_action($mcpContextHook, $invalidateMcpContext);
241 }
242