PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.11.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.11.0
2.11.0 2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 All 78 releases
← All changes | app/Models/BaseSpace.php +80 -62 2.4.012.11.0 View file →
@@ -6,10 +6,34 @@
6 6 use FluentCommunity\App\Functions\Utility;
7 7 use FluentCommunity\App\Services\CustomSanitizer;
8 8 use FluentCommunity\App\Services\LockscreenService;
9 9 use FluentCommunity\App\Services\Helper;
10 +use FluentCommunity\App\Services\SpaceMenuService;
10 11 use FluentCommunity\Framework\Support\Arr;
11 12
13 +/**
14 + * @property int $id
15 + * @property int|null $created_by
16 + * @property int|null $parent_id
17 + * @property string $title
18 + * @property string $slug
19 + * @property string|null $description
20 + * @property string|null $logo
21 + * @property string|null $cover_photo
22 + * @property string|null $type
23 + * @property string|null $privacy
24 + * @property string|null $status
25 + * @property int|null $serial
26 + * @property array $settings
27 + * @property string|null $created_at
28 + * @property string|null $updated_at
29 + * @property array|null $permissions
30 + * @property string|null $description_rendered
31 + * @property mixed $membership
32 + * @property array|null $topics
33 + * @property array|null $header_links
34 + * @property array|null $lockscreen_config
35 + */
12 36 class BaseSpace extends Model
13 37 {
14 38 protected $table = 'fcom_spaces';
15 39
@@ -14,9 +38,9 @@
14 38 protected $table = 'fcom_spaces';
15 39
16 40 protected static $type = 'community';
17 41
18 - protected $guarded = ['id'];
42 + protected $guarded = [ 'id' ];
19 43
20 44 protected $fillable = [
21 45 'created_by',
22 46 'parent_id',
@@ -28,14 +52,14 @@
28 52 'type',
29 53 'privacy',
30 54 'status',
31 55 'serial',
32 - 'settings'
56 + 'settings',
33 57 ];
34 58
35 59 protected $searchable = [
36 60 'title',
37 - 'description'
61 + 'description',
38 62 ];
39 63
40 64 public $_preloadedMembershipUserId = null;
41 65 public $_preloadedMembership = null;
@@ -65,11 +89,11 @@
65 89 });
66 90
67 91 static::deleting(function ($space) {
68 92 Media::where('sub_object_id', $space->id)
69 - ->whereIn('object_source', ['space_logo', 'space_cover_photo'])
93 + ->whereIn('object_source', [ 'space_logo', 'space_cover_photo' ])
70 94 ->update([
71 - 'is_active' => 0
95 + 'is_active' => 0,
72 96 ]);
73 97 });
74 98 }
75 99
@@ -108,9 +132,9 @@
108 132 }
109 133
110 134 public function scopeOnlyMain($query)
111 135 {
112 - return $query->withoutGlobalScopes()->whereIn('type', ['community', 'course']);
136 + return $query->withoutGlobalScopes()->whereIn('type', [ 'community', 'course' ]);
113 137 }
114 138
115 139 public function scopeFilterByUserId($query, $userId)
116 140 {
@@ -153,15 +177,15 @@
153 177
154 178 public function members()
155 179 {
156 180 return $this->belongsToMany(User::class, 'fcom_space_user', 'space_id', 'user_id')
157 - ->withPivot(['role', 'created_at', 'status']);
181 + ->withPivot([ 'role', 'created_at', 'status' ]);
158 182 }
159 183
160 184 public function x_members()
161 185 {
162 186 return $this->belongsToMany(XProfile::class, 'fcom_space_user', 'space_id', 'user_id', 'id', 'user_id')
163 - ->withPivot(['role', 'created_at', 'status']);
187 + ->withPivot([ 'role', 'created_at', 'status' ]);
164 188 }
165 189
166 190 public function group()
167 191 {
@@ -196,9 +220,9 @@
196 220
197 221 foreach ($spaces as $space) {
198 222 $space->_preloadedMembershipUserId = $userId;
199 223 $pivot = $pivots->get($space->id);
200 - $space->_preloadedMembership = $pivot ? static::pivotToMembership($pivot) : null;
224 + $space->_preloadedMembership = $pivot ? self::pivotToMembership($pivot) : null;
201 225 }
202 226 }
203 227
204 228 private static function pivotToMembership($pivot)
@@ -219,9 +243,9 @@
219 243 if (Helper::isSiteAdmin($userId)) {
220 244 return true;
221 245 }
222 246
223 - $roles = ['admin'];
247 + $roles = [ 'admin' ];
224 248
225 249 if ($checkModerator) {
226 250 if (Helper::isModerator()) {
227 251 return true;
@@ -265,13 +289,13 @@
265 289 if (isset($data['parent_id'])) {
266 290 if (!empty($data['parent_id'])) {
267 291 $group = SpaceGroup::find($data['parent_id']);
268 292 if (!$group) {
269 - throw new \Exception('Invalid group id', 400);
293 + throw new \Exception(esc_html__('Invalid group id', 'fluent-community'), 400);
270 294 }
271 295 $this->parent_id = $group->id;
272 296 } else {
273 - $this->parent_id = NULL;
297 + $this->parent_id = null;
274 298 }
275 299 }
276 300
277 301 if (isset($data['settings'])) {
@@ -283,8 +307,9 @@
283 307 }
284 308
285 309 $exisitingSetting = $this->settings;
286 310 $settings['links'] = Arr::get($exisitingSetting, 'links', []);
311 + $settings[SpaceMenuService::SETTINGS_KEY] = Arr::get($exisitingSetting, SpaceMenuService::SETTINGS_KEY, []);
287 312
288 313 if (isset($settings['og_image'])) {
289 314 $ogImageUrl = Arr::get($settings, 'og_image');
290 315 if ($ogImageUrl) {
@@ -290,14 +315,14 @@
290 315 if ($ogImageUrl) {
291 316 $ogImageMedia = Helper::getMediaFromUrl($ogImageUrl);
292 317 if ($ogImageMedia && $ogImageMedia->is_active) {
293 318 unset($settings['og_image']);
294 - } else if ($ogImageMedia) {
319 + } elseif ($ogImageMedia) {
295 320 $ogImageMedia->update([
296 321 'is_active' => true,
297 322 'user_id' => get_current_user_id(),
298 323 'sub_object_id' => $this->id,
299 - 'object_source' => 'space_og_media'
324 + 'object_source' => 'space_og_media',
300 325 ]);
301 326 $settings['og_image'] = $ogImageMedia->public_url;
302 327 } else {
303 328 $settings['og_image'] = sanitize_url($ogImageUrl);
@@ -352,9 +377,9 @@
352 377 }
353 378
354 379 public function isContentSpace()
355 380 {
356 - return in_array($this->type, ['community', 'course']);
381 + return in_array($this->type, [ 'community', 'course' ]);
357 382 }
358 383
359 384 public function getSettingsAttribute($value)
360 385 {
@@ -363,9 +388,16 @@
363 388 if (!$settings) {
364 389 $settings = [];
365 390 }
366 391
367 - return wp_parse_args($settings, $this->defaultSettings());
392 + $settings = wp_parse_args($settings, $this->defaultSettings());
393 +
394 + if (!defined('FLUENT_COMMUNITY_PRO')) {
395 + $settings['document_library'] = 'no';
396 + $settings['media_gallery'] = 'no';
397 + }
398 +
399 + return $settings;
368 400 }
369 401
370 402 public function defaultSettings()
371 403 {
@@ -393,9 +425,10 @@
393 425 public function getPublicPermissions()
394 426 {
395 427 if ($this->privacy == 'public') {
396 428
397 - $hasDocuments = defined('FLUENT_COMMUNITY_PRO') && Arr::get($this->settings, 'document_library') == 'yes';
429 + $hasDocuments = defined('FLUENT_COMMUNITY_PRO') && Arr::get($this->settings, 'document_library') == 'yes';
430 + $hasMediaGallery = defined('FLUENT_COMMUNITY_PRO') && Arr::get($this->settings, 'media_gallery') == 'yes';
398 431
399 432 return [
400 433 'can_view_info' => true,
401 434 'can_view_posts' => true,
@@ -400,9 +433,10 @@
400 433 'can_view_info' => true,
401 434 'can_view_posts' => true,
402 435 'can_view_members' => $this->canViewMembers(null),
403 436 'can_create_post' => false,
404 - 'can_view_documents' => $hasDocuments && Arr::get($this->settings, 'document_access') == 'everybody'
437 + 'can_view_documents' => $hasDocuments && Arr::get($this->settings, 'document_access') == 'everybody',
438 + 'can_view_media' => $hasMediaGallery && Arr::get($this->settings, 'media_access') == 'everybody',
405 439 ];
406 440 }
407 441
408 442 return [
@@ -449,9 +483,10 @@
449 483
450 484 $hasPermission = $permissions[$permission] ?? false;
451 485
452 486 if (!$hasPermission && $exception) {
453 - throw new \Exception('Sorry you do not have permission ' . esc_html($permission), 403);
487 + /* translators: %s is the permission name */
488 + throw new \Exception(esc_html(sprintf(__('Sorry you do not have permission %s', 'fluent-community'), $permission)), 403);
454 489 }
455 490
456 491 return $hasPermission;
457 492 }
@@ -460,26 +495,30 @@
460 495 {
461 496 return $this->updateCustomMeta('lockscreen_settings', $settingFields);
462 497 }
463 498
499 + /**
500 + * Sidebar links, emails, invitations, canonical URLs and API payloads all resolve
501 + * through here, so the filter moves every one of them together.
502 + *
503 + * @return string
504 + */
464 505 public function getPermalink()
465 506 {
507 + $permalink = Helper::baseUrl('/');
508 +
466 509 if ($this->type == 'community') {
467 - return Helper::baseUrl('space/' . $this->slug . '/home');
468 - }
469 -
470 - if ($this->type == 'course') {
471 - return Helper::baseUrl('course/' . $this->slug . '/lessons');
472 - }
473 -
474 - if ($this->type == 'sidebar_link') {
475 - $permalink = Arr::get($this->settings, 'permalink');
476 - if ($permalink) {
477 - return $permalink;
510 + $permalink = Helper::baseUrl('space/' . $this->slug . '/home');
511 + } elseif ($this->type == 'course') {
512 + $permalink = Helper::baseUrl('course/' . $this->slug . '/lessons');
513 + } elseif ($this->type == 'sidebar_link') {
514 + $customLink = Arr::get($this->settings, 'permalink');
515 + if ($customLink) {
516 + $permalink = $customLink;
478 517 }
479 518 }
480 519
481 - return Helper::baseUrl('/');
520 + return apply_filters('fluent_community/space_permalink', $permalink, $this);
482 521 }
483 522
484 523 public function getLockscreen()
485 524 {
@@ -507,16 +546,16 @@
507 546 return '';
508 547 }
509 548
510 549 if ($this->logo) {
511 - return '<img alt="" src="' . $this->logo . '"/>';
550 + return '<img alt="" src="' . esc_url($this->logo) . '"/>';
512 551 }
513 552
514 - if ($imoji = Arr::get($this->settings, 'emoji')) {
553 + if ($imoji = Arr::get($this->settings, 'emoji')) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
515 554 return '<span class="fcom_emoji">' . $imoji . '</span>';
516 555 }
517 556
518 - if ($svg = Arr::get($this->settings, 'shape_svg')) {
557 + if ($svg = Arr::get($this->settings, 'shape_svg')) { // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
519 558 return '<span class="fcom_shape"><i class="el-icon">' . $svg . '</i></span>';
520 559 }
521 560
522 561 return '';
@@ -542,9 +581,9 @@
542 581 // We have to create one
543 582 $new = Meta::create([
544 583 'object_id' => $topicId,
545 584 'meta_key' => $this->id, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
546 - 'object_type' => 'term_space_relation'
585 + 'object_type' => 'term_space_relation',
547 586 ]);
548 587
549 588 $existIds[] = $new->id;
550 589 }
@@ -565,13 +604,14 @@
565 604 if ($newModel->title) {
566 605 // Remove the emojis
567 606 $title = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $newModel->title);
568 607 // get the first 30 char from the title
569 - $title = substr($title, 0, 30);
608 + $title = mb_substr($title, 0, 30, 'UTF-8');
570 609 } else {
571 610 $title = static::$type . '-' . time();
572 611 }
573 612
613 + $title = Helper::normalizeToAscii($title);
574 614 $title = remove_accents($title);
575 615
576 616 $title = strtolower($title);
577 617
@@ -587,10 +627,10 @@
587 627 while (self::withoutGlobalScopes()->where('slug', $slug)->exists()) {
588 628 if ($count == 5) {
589 629 $count = time();
590 630 }
591 - $slug = $title . '-' . ++$slugNum;
592 - $count++;
631 + $slug = $title . '-' . (++$slugNum);
632 + ++$count;
593 633 }
594 634
595 635 return $slug;
596 636 }
@@ -603,28 +643,10 @@
603 643 $this->description_rendered = wpautop($this->description);
604 644 $this->membership = $this->getMembership($userId);
605 645 $this->topics = Utility::getTopicsBySpaceId($this->id);
606 646
607 - $headerLinks = [
608 - [
609 - 'title' => __('Posts', 'fluent-community'),
610 - 'route' => [
611 - 'name' => 'space_feeds',
612 - ]
613 - ]
614 - ];
647 + $this->header_links = SpaceMenuService::getMenuLinks($this, $user);
615 648
616 - if (Arr::get($this->permissions, 'can_view_members')) {
617 - $headerLinks[] = [
618 - 'title' => __('Members', 'fluent-community'),
619 - 'route' => [
620 - 'name' => 'space_members',
621 - ]
622 - ];
623 - }
624 -
625 - $this->header_links = apply_filters('fluent_community/space_header_links', $headerLinks, $this);
626 -
627 649 if ($this->isAdmin($userId, true)) {
628 650 return $this;
629 651 }
630 652
@@ -631,13 +653,9 @@
631 653 $this->lockscreen_config = LockscreenService::getLockscreenConfig($this, $this->membership, true);
632 654
633 655 $spaceSettings = $this->settings;
634 656
635 - $spaceLinks = Arr::get($spaceSettings, 'links', []);
636 -
637 - $spaceSettings['links'] = array_values(array_filter($spaceLinks, function ($item) use ($user) {
638 - return Helper::isLinkAccessible($item, $user);
639 - }));
657 + $spaceSettings['links'] = Helper::filterAccessibleLinks(Arr::get($spaceSettings, 'links', []), $user);
640 658
641 659 $this->settings = $spaceSettings;
642 660
643 661 return $this;