PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / trunk
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration vtrunk
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 / Functions / helpers.php

helpers.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration trunk, at app/Functions/helpers.php

333 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use FluentBoards\App\App;
4
5 // $app is available
6
7 if (!function_exists('fluentBoards')) {
8 function fluentBoards($module = null)
9 {
10 return App::getInstance($module);
11 }
12 }
13
14 if (!function_exists('FluentBoardsApi')) {
15 function FluentBoardsApi($key = null)
16 {
17 $api = fluentBoards('api');
18 return is_null($key) ? $api : $api->{$key};
19 }
20 }
21
22 if (!function_exists('fluent_boards_sanitize_description')) {
23 function fluent_boards_sanitize_description($description): string
24 {
25 $description = preg_replace_callback('/<((?:https?:\/\/)[^<>\s]+)>/i', function ($matches) {
26 $url = esc_url_raw(html_entity_decode($matches[1], ENT_QUOTES | ENT_HTML5, 'UTF-8'));
27
28 return $url ? '[' . $url . '](' . str_replace(')', '%29', $url) . ')' : $matches[0];
29 }, (string) $description);
30
31 return wp_kses_post($description);
32 }
33 }
34
35 if (!function_exists('fluent_boards_user_avatar')) {
36 function fluent_boards_user_avatar($email, $name = '')
37 {
38 $user = get_user_by('email', $email);
39
40 if ($user) {
41 $photo_url = get_user_meta($user->ID, 'fbs_profile_photo', true);
42 if ($photo_url) {
43 return apply_filters('fluent_boards/get_avatar', $photo_url, $email);
44 }
45
46 $has_custom_avatar = get_user_meta($user->ID, 'wp_user_avatar', true);
47 if ($has_custom_avatar) {
48 $custom_avatar_attachment = get_post($has_custom_avatar);
49 if ($custom_avatar_attachment) {
50 $avatar_url = wp_get_attachment_url($has_custom_avatar);
51 return apply_filters('fluent_boards/get_avatar', $avatar_url, $email);
52 }
53 }
54 $avatar_url = get_avatar_url($user->ID, array('size' => 128));
55 return apply_filters('fluent_boards/get_avatar', $avatar_url, $email);
56 }
57
58 $hash = md5(strtolower(trim($email)));
59 /**
60 * Gravatar URL by Email
61 *
62 * @return string $gravatar url of the gravatar image
63 */
64 $fallback = '';
65 if ($name) {
66 $fallback = '&d=https%3A%2F%2Fui-avatars.com%2Fapi%2F' . urlencode($name) . '/128';
67 }
68
69 return apply_filters('fluent_boards/get_avatar',
70 "https://www.gravatar.com/avatar/{$hash}?s=128" . $fallback,
71 $email
72 );
73 }
74 }
75
76 if (!function_exists('fluent_boards_mix')) {
77 function fluent_boards_mix($path, $manifestDirectory = '')
78 {
79 return fluentBoards('url.assets') . ltrim($path, '/');
80 }
81 }
82
83 if (!function_exists('FluentBoardsAssetUrl')) {
84 function FluentBoardsAssetUrl($path = null)
85 {
86 $assetUrl = fluentBoards('url.assets');
87
88 return $path ? ($assetUrl . $path) : $assetUrl;
89 }
90 }
91
92 if (!function_exists('fluent_boards_page_url')) {
93 function fluent_boards_page_url(): ?string
94 {
95 return apply_filters('fluent_boards/app_url', admin_url('admin.php?page=fluent-boards#/'));
96 }
97 }
98
99 if (!function_exists('fluent_boards_is_rtl')) {
100 /**
101 * Determine if Fluent Boards should render right-to-left UI.
102 *
103 * @return bool
104 */
105 function fluent_boards_is_rtl(): bool
106 {
107 return is_rtl();
108 }
109 }
110
111 function fluent_boards_get_pref_settings($cached = true)
112 {
113 static $pref = null;
114
115 if ($cached && $pref) {
116 return $pref;
117 }
118
119 $settings = [
120 'timeTracking' => [
121 'enabled' => 'no',
122 'all_boards' => 'yes',
123 'selected_boards' => []
124 ],
125 'frontend' => [
126 'enabled' => 'no',
127 'slug' => 'projects',
128 'render_type' => 'standalone',
129 'page_id' => ''
130 ],
131 'menu_settings' => [
132 'in_fluent_crm' => 'no',
133 'menu_position' => 3
134 ],
135 'recurring_task' => [
136 'enabled' => 'no',
137 'all_boards' => 'yes',
138 'selected_boards' => []
139 ],
140 ];
141
142 $storedSettings = get_option('fluent_boards_modules', []);
143 if ($storedSettings && is_array($storedSettings)) {
144 $settings = wp_parse_args($storedSettings, $settings);
145 }
146
147 $pref = $settings;
148
149 return $settings;
150 }
151
152 if (!function_exists('fluent_boards_site_logo')) {
153 function fluent_boards_site_logo()
154 {
155 $logo_url = '';
156 if (function_exists('get_custom_logo') && has_custom_logo()) {
157 $custom_logo_id = get_theme_mod('custom_logo');
158 $logo = wp_get_attachment_image_src($custom_logo_id, 'full');
159 if ($logo) {
160 $logo_url = $logo[0];
161 }
162 }
163 return apply_filters('fluent_boards/site_logo', $logo_url);
164 }
165 }
166
167 function fluent_boards_get_option($key, $default = null)
168 {
169 $exit = \FluentBoards\App\Models\Meta::where('object_type', 'option')
170 ->where('key', $key)
171 ->first();
172
173 if ($exit) {
174 return $exit->value;
175 }
176
177 return $default;
178 }
179
180 function fluent_boards_update_option($key, $value)
181 {
182 $exit = \FluentBoards\App\Models\Meta::where('object_type', 'option')
183 ->where('key', $key)
184 ->first();
185
186 if ($exit) {
187 $exit->value = $value;
188 $exit->save();
189 } else {
190 $exit = \FluentBoards\App\Models\Meta::create([
191 'object_type' => 'option',
192 'key' => $key,
193 'value' => $value
194 ]);
195 }
196
197 return $exit;
198 }
199
200
201 function fluentBoardsDb()
202 {
203 return fluentBoards('db');
204 }
205
206 /**
207 * Retrieves features configuration.
208 *
209 * @deprecated 1.90 Use fluent_boards_get_features_config() instead.
210 */
211 function fbsGetFeaturesConfig()
212 {
213 _deprecated_function(__FUNCTION__, '1.90', 'fluent_boards_get_features_config');
214 return fluent_boards_get_features_config();
215 }
216
217 function fluent_boards_get_features_config()
218 {
219 $features = fluent_boards_get_option('_fbs_features', []);
220
221 $defaults = [
222 'cloud_storage' => 'no',
223 // more advanced features/config can be added here
224 ];
225
226 if (defined('FLUENT_BOARDS_CLOUD_STORAGE') && FLUENT_BOARDS_CLOUD_STORAGE) {
227 $features['cloud_storage'] = 'yes';
228 }
229
230 return wp_parse_args($features, $defaults);
231 }
232
233 /**
234 * Updates an option value.
235 *
236 * @deprecated 1.90 Use fluent_boards_get_option() instead.
237 */
238 function fbsGetOption($key, $default = null)
239 {
240 _deprecated_function(__FUNCTION__, '1.90', 'fluent_boards_get_option');
241 return fluent_boards_get_option($key, $default);
242 }
243
244 /**
245 * Updates an option value.
246 *
247 * @deprecated 1.90 Use fluent_boards_update_option() instead.
248 */
249 function fbsUpdateOption($key, $value)
250 {
251 _deprecated_function(__FUNCTION__, '1.90', 'fluent_boards_update_option');
252 return fluent_boards_update_option($key, $value);
253 }
254
255
256 function fluentboardsCsvMimes()
257 {
258 /**
259 * Board Import CSV Mimes
260 *
261 * @return array array of CSV mimes
262 */
263 return apply_filters('fluent_boards_csv_mimes', [
264 'text/csv',
265 'text/plain',
266 'application/csv',
267 'text/comma-separated-values',
268 'application/excel',
269 'application/vnd.ms-excel',
270 'application/vnd.msexcel',
271 'text/anytext',
272 'application/octet-stream',
273 'application/txt'
274 ]);
275 }
276
277 function fluent_boards_string_to_bool($value)
278 {
279 // Normalize known string values to booleans
280 $trueFalseMap = [
281 'yes' => true,
282 'no' => false,
283 'true' => true,
284 'false' => false,
285 '1' => true,
286 '0' => false,
287 true => true,
288 false => false,
289 ];
290
291 // Allow modification of the map
292 $trueFalseMap = apply_filters('fluent_boards/true_false_convert', $trueFalseMap);
293
294 // Handle array input recursively
295 if (is_array($value)) {
296 return array_map('fluent_boards_string_to_bool', $value);
297 }
298
299 // Normalize string input
300 $key = is_string($value) ? strtolower(trim($value)) : $value;
301
302 // Match normalized value against map
303 if (array_key_exists($key, $trueFalseMap)) {
304 return $trueFalseMap[$key];
305 }
306
307 // Fallback: return original value if not recognized
308 return $value;
309 }
310
311 /**
312 * Builds the canonical Fluent Boards Upgrade-to-Pro URL.
313 *
314 * @param string $utmContent Exact in-plugin CTA placement.
315 * @return string
316 */
317 function fluent_boards_get_upgrade_url($utmContent = '')
318 {
319 $queryArgs = [
320 'utm_source' => 'fluent-boards',
321 'utm_medium' => 'free_plugin',
322 'utm_campaign' => 'upgrade_pro',
323 'utm_term' => FLUENT_BOARDS_PLUGIN_VERSION,
324 ];
325
326 $utmContent = sanitize_key($utmContent);
327 if ($utmContent) {
328 $queryArgs['utm_content'] = $utmContent;
329 }
330
331 return add_query_arg($queryArgs, 'https://fluentboards.com/pricing/');
332 }
333