PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.1.0
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.1.0
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
← All changes | app/Models/Board.php +143 -20 1.122.1.0 View file →
@@ -1,14 +1,13 @@
1 1 <?php
2 2
3 3 namespace FluentBoards\App\Models;
4 4
5 -use FluentBoards\App\Services\BoardService;
6 5 use FluentBoards\App\Services\Constant;
7 6 use FluentBoards\App\Services\PermissionManager;
8 7 use FluentBoards\App\Services\UserService;
9 8 use FluentBoards\Framework\Database\Orm\Builder;
10 -use FluentBoards\Framework\Support\Arr;
9 +use FluentBoardsPro\App\Models\CustomField;
11 10
12 11 class Board extends Model
13 12 {
14 13 protected $table = 'fbs_boards';
@@ -31,20 +30,24 @@
31 30 'created_by',
32 31 'archived_at',
33 32 ];
34 33
34 + protected $appends = ['meta', 'isUserOnlyViewer'];
35 +
36 + /**
37 + * Boot board defaults while preserving empty backgrounds for newly created boards.
38 + */
35 39 public static function boot()
36 40 {
37 41 static::creating(function ($model) {
38 42 $model->created_by = $model->created_by ?: get_current_user_id();
39 43 $model->type = $model->type ?: 'to-do'; // default board type is to-do
40 - $model->background = $model->background ?: $model->randomBackground();
44 + $model->background = $model->background ?: '';
41 45 });
42 46 /* global scope for board type which means only type = to-do will be fetched from everywhere */
43 47 parent::boot();
44 48 static::addGlobalScope('type', function (Builder $builder) {
45 - $builder = $builder->whereNull('archived_at');
46 - $builder->where('type', '=', 'to-do')
49 + $builder = $builder->where('type', '=', 'to-do')
47 50 ->orWhere('type', '=', 'roadmap');
48 51 });
49 52 }
50 53
@@ -76,8 +79,13 @@
76 79 {
77 80 return \maybe_unserialize($settings);
78 81 }
79 82
83 + public function getMetaAttribute()
84 + {
85 + return $this->getMeta();
86 + }
87 +
80 88 public function setBackgroundAttribute($background)
81 89 {
82 90 $this->attributes['background'] = \maybe_serialize($background);
83 91 }
@@ -95,16 +103,12 @@
95 103 public function completedTasks()
96 104 {
97 105 return $this->hasMany(Task::class, 'board_id')
98 106 ->whereNull('archived_at')
107 + ->where('parent_id', null)
99 108 ->where('status', 'closed');
100 109 }
101 110
102 - public function boardTerm()
103 - {
104 - return $this->hasMany(BoardTerm::class, 'board_id');
105 - }
106 -
107 111 public function stages()
108 112 {
109 113 return $this->hasMany(Stage::class, 'board_id')
110 114 ->whereNull('archived_at')
@@ -124,9 +128,9 @@
124 128 User::class,
125 129 'fbs_relations',
126 130 'object_id',
127 131 'foreign_id'
128 - )->withPivot('settings')
132 + )->withPivot('settings','preferences')
129 133 ->wherePivot('object_type', Constant::OBJECT_TYPE_BOARD_USER)
130 134 ->withTimestamps();
131 135 }
132 136
@@ -215,23 +219,142 @@
215 219 }
216 220
217 221 return $query->whereIn('id', $boardIds);
218 222 }
219 - private function randomBackground()
223 +
224 + /**
225 + * Exclude template boards (settings['is_template'] === true).
226 + * The settings column is serialized text, so both the PHP-serialized
227 + * and JSON representations of the flag are matched.
228 + */
229 + public function scopeExcludeTemplates($query)
220 230 {
221 - $solids = Constant::BOARD_BACKGROUND_DEFAULT_SOLID_COLORS;
222 - $solid = $solids[wp_rand(0, count($solids) - 1)];
231 + return $query->where(function ($query) {
232 + $query->whereNull('settings')
233 + ->orWhere(function ($subQuery) {
234 + $subQuery->where('settings', 'NOT LIKE', '%"is_template";b:1%')
235 + ->where('settings', 'NOT LIKE', '%"is_template":true%');
236 + });
237 + });
238 + }
223 239
224 - return [
225 - 'id' => $solid['id'],
226 - 'is_image' => false,
227 - 'image_url' => null,
228 - 'color' => $solid['value']
229 - ];
240 + /**
241 + * Limit boards to types supported by the currently loaded plugins.
242 + */
243 + public function scopeAvailableInCurrentInstall($query)
244 + {
245 + if (!defined('FLUENT_ROADMAP')) {
246 + return $query->where('type', 'to-do');
247 + }
248 +
249 + return $query;
230 250 }
231 251
252 + /**
253 + * Only template boards (inverse of scopeExcludeTemplates).
254 + */
255 + public function scopeOnlyTemplates($query)
256 + {
257 + return $query->whereNotNull('settings')
258 + ->where(function ($subQuery) {
259 + $subQuery->where('settings', 'LIKE', '%"is_template";b:1%')
260 + ->orWhere('settings', 'LIKE', '%"is_template":true%');
261 + });
262 + }
263 +
232 264 public function getUsers()
233 265 {
234 266 return (new UserService())->allFluentBoardsUsers($this->id);
267 + }
268 +
269 + public function customFields()
270 + {
271 + return $this->hasMany(CustomField::class, 'board_id')
272 + ->whereNull('archived_at')
273 + ->orderBy('position', 'asc');
274 + }
275 +
276 + public function getMeta() // get Board Meta only
277 + {
278 + $meta = Meta::where('object_id', $this->id)
279 + ->where('object_type', Constant::OBJECT_TYPE_BOARD)
280 + ->get();
281 +
282 + $formattedMeta = [];
283 +
284 + foreach ($meta as $m) {
285 + $formattedMeta[$m->key] = $m->value;
286 + }
287 +
288 + return $formattedMeta;
289 + }
290 +
291 +
292 +
293 + public function getMetaByKey($key) // get Board Meta only
294 + {
295 + $meta = Meta::where('object_id', $this->id)
296 + ->where('object_type', Constant::OBJECT_TYPE_BOARD)
297 + ->where('key', $key)
298 + ->first();
299 +
300 + return $meta->value ?? null;
301 + }
302 +
303 + public function updateMeta($key, $value)
304 + {
305 + $meta = Meta::where('object_id', $this->id)
306 + ->where('object_type', Constant::OBJECT_TYPE_BOARD)
307 + ->where('key', $key)
308 + ->first();
309 +
310 + if ($meta) {
311 + $meta->value = $value;
312 + $meta->save();
313 + } else {
314 + $meta = Meta::create([
315 + 'object_id' => $this->id,
316 + 'object_type' => Constant::OBJECT_TYPE_BOARD,
317 + 'key' => $key,
318 + 'value' => $value,
319 + ]);
320 + }
321 +
322 + return $meta;
323 +
324 + }
325 +
326 +
327 + public function activities()
328 + {
329 + return $this->hasMany(Activity::class, 'object_id')
330 + ->where('object_type', Constant::ACTIVITY_BOARD);
331 + }
332 +
333 + public function getisUserOnlyViewerAttribute()
334 + {
335 + $userId = get_current_user_id();
336 + if(PermissionManager::isAdmin()) {
337 + return false;
338 + }
339 + $boardPermissions = Relation::where('object_id', $this->id)
340 + ->where('foreign_id', $userId)
341 + ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
342 + ->first();
343 +
344 + return $boardPermissions->settings['is_viewer_only'] ?? false;
345 + }
346 +
347 + public function removeBoardFromFolder()
348 + {
349 + $relation = Relation::where('object_type', Constant::OBJECT_TYPE_FOLDER_BOARD)
350 + ->where('foreign_id', $this->id)
351 + ->first();
352 +
353 + if (!$relation) {
354 + return;
355 + }
356 + $relation->delete();
357 +
235 358 }
236 359
237 360 }