PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.99
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.99
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 1.1.0 All 77 releases
fluent-community / app / Hooks / Handlers / EmailNotificationHandler.php

EmailNotificationHandler.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.99, at app/Hooks/Handlers/EmailNotificationHandler.php

683 lines 24.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\App\Hooks\Handlers;
4
5 use FluentCommunity\App\Functions\Utility;
6 use FluentCommunity\App\Models\Comment;
7 use FluentCommunity\App\Models\Feed;
8 use FluentCommunity\App\Models\Notification;
9 use FluentCommunity\App\Models\BaseSpace;
10 use FluentCommunity\App\Models\SpaceUserPivot;
11 use FluentCommunity\App\Models\User;
12 use FluentCommunity\App\Models\XProfile;
13 use FluentCommunity\App\Services\Helper;
14 use FluentCommunity\App\Services\Libs\DailyDigest;
15 use FluentCommunity\App\Services\Libs\Mailer;
16 use FluentCommunity\App\Services\NotificationPref;
17 use FluentCommunity\App\Services\ProfileHelper;
18 use FluentCommunity\Framework\Support\Arr;
19
20 class EmailNotificationHandler
21 {
22
23 private $maxRunTime = 0;
24
25 public function register()
26 {
27 add_action('fluent_community/space_feed/created', [$this, 'handleSpaceFeedCreated'], 10, 1);
28 add_action('fluent_community/email_notify_new_posts', [$this, 'notifyOnPostCreatedAsync'], 10, 1);
29
30 add_action('fluent_community/comment_added', [$this, 'handleNewCommentEvent'], 30, 2);
31 add_action('fluent_community/comment_added_async', [$this, 'handleNewCommentNotificationAsync'], 10, 2);
32
33 /*
34 * This is an async request
35 */
36 add_action('fluent_community/email_notify_users_everyone_tag', [$this, 'emailNotifyUsersForEveryoneTag'], 10, 2);
37
38 add_action('fluent_community_send_daily_digest', [$this, 'maybeSendDailyDigest'], 10);
39 add_action('fluent_community/space/join_requested', [$this, 'handleCommunityJoinRequest'], 10, 2);
40 }
41
42 public function handleSpaceFeedCreated($feed)
43 {
44 if (did_action('fluent_community/feed/scheduling_everyone_tag')) {
45 return;
46 }
47
48 $space = $feed->space;
49 if (!$space) {
50 return false;
51 }
52
53 $types = ['np_by_member_mail'];
54 $spaceRole = $feed->user->getSpaceRole($feed->space);
55 if (!in_array($spaceRole, ['admin', 'moderator'])) {
56 $types[] = 'np_by_admin_mail';
57 }
58
59 $hasSubscribers = User::whereHas('notificationSubscriptions', function ($query) use ($types, $space) {
60 $query->where(function ($q) use ($types, $space) {
61 $q->whereIn('notification_type', $types)
62 ->where('object_id', $space->id)
63 ->where('is_read', 1);
64 });
65 })->exists();
66
67 if ($hasSubscribers) {
68 // We are scheduling this after 2 minutes of the post publish for performance
69 as_schedule_single_action(time() + 120, 'fluent_community/email_notify_new_posts', [
70 $feed->id
71 ], 'fluent-community');
72 }
73 }
74
75 public function notifyOnPostCreatedAsync($feedId)
76 {
77 if (!$this->maxRunTime) {
78 $this->maxRunTime = Utility::getMaxRunTime();
79 }
80
81 if (is_numeric($feedId)) {
82 $feed = Feed::find($feedId);
83 } else {
84 $feed = $feedId;
85 }
86
87 if (!$feed || !$feed instanceof Feed) {
88 return;
89 }
90
91 $space = $feed->space;
92 if (!$space || !$feed->user) {
93 return;
94 }
95
96 $types = ['np_by_member_mail'];
97 $spaceRole = $feed->user->getSpaceRole($feed->space);
98 if (in_array($spaceRole, ['admin', 'moderator'])) {
99 $types[] = 'np_by_admin_mail';
100 }
101
102 $lastSendUserId = (int)$feed->getCustomMeta('_last_email_user_id', 0);
103
104 $users = User::whereHas('notificationSubscriptions', function ($query) use ($types, $space) {
105 $query->whereIn('notification_type', $types)
106 ->where('object_id', $space->id)
107 ->where('is_read', 1);
108 })
109 ->whereHas('space_pivot', function ($query) use ($space) {
110 $query->where('space_id', $space->id)
111 ->where('status', 'active');
112 })
113 ->when($lastSendUserId, function ($q) use ($lastSendUserId) {
114 $q->where('ID', '>', $lastSendUserId);
115 })
116 ->whereHas('xprofile', function ($query) {
117 return $query->where('status', 'active');
118 })
119 ->orderBy('ID', 'ASC')
120 ->limit(60)
121 ->get();
122
123 if ($users->isEmpty()) {
124 return; // It's done
125 }
126
127 $emailSubject = \sprintf(
128 /* translators: %1$s is the author name and %2$s is the post excerpt (max 30 chars) */
129 __('New Post By %1$s: %2$s', 'fluent-community'),
130 $feed->user->getDisplayName(),
131 $feed->getHumanExcerpt(30)
132 );
133
134 $emailBody = $this->getFeedHtml($feed, true);
135
136 /*
137 * must need to replace these two strings
138 * ##feed_permalink##
139 * ##email_notification_url##
140 */
141 $feedLink = $feed->getPermalink();
142
143 $startTime = microtime(true);
144 $maxSendPerSecond = 10; // max 10 emails per second
145
146 foreach ($users as $index => $user) {
147 $feed->updateCustomMeta('_last_email_user_id', $user->ID);
148 if ($user->ID == $feed->user_id) {
149 continue;
150 }
151
152 $newEmailBody = str_replace([
153 '##feed_permalink##',
154 '##email_notification_url##'
155 ], [
156 ProfileHelper::signUserUrlWithAuthHash($feedLink, $user->ID),
157 ProfileHelper::getSignedNotificationPrefUrl($user->ID)
158 ], $emailBody);
159
160 $mailer = new Mailer('', $emailSubject, $newEmailBody);
161 $mailer->to($user->user_email, $user->display_name);
162 $mailer->send();
163
164 if (microtime(true) - FLUENT_COMMUNITY_START_TIME > $this->maxRunTime) {
165 // It's been 45 seconds, let's stop and schedule the next one and schedule a new one
166 as_schedule_single_action(time(), 'fluent_community/email_notify_new_posts', [$feed->id], 'fluent-community');
167 return true;
168 }
169
170 if (($index + 1) % $maxSendPerSecond == 0) {
171 $timeTaken = microtime(true) - $startTime;
172 if ($timeTaken < 1) {
173 usleep(1000000 - ($timeTaken * 1000000));
174 }
175 $startTime = microtime(true);
176 }
177 }
178
179 return $this->notifyOnPostCreatedAsync($feed);
180 }
181
182 public function handleNewCommentEvent(Comment $comment, $feed)
183 {
184 if ($comment->parent_id) {
185 $globalCommentStatus = $this->isEnabled('reply_my_com_mail');
186 } else {
187 $globalCommentStatus = $this->isEnabled('com_my_post_mail');
188 }
189
190 $notificationUserIds = [];
191 if ($comment->user_id != $feed->user_id && NotificationPref::willGetCommentEmail($feed->user_id, $globalCommentStatus)) {
192 as_schedule_single_action(time(), 'fluent_community/comment_added_async', [$comment->id, 0], 'fluent-community');
193 return true;
194 }
195
196 if ($comment->parent_id) {
197 $notificationUserIds = $comment->getCommentParentUserIds();
198 $notificationUserIds = array_filter($notificationUserIds, function ($userId) use ($globalCommentStatus) {
199 return NotificationPref::willGetCommentReplyEmail($userId, $globalCommentStatus);
200 });
201 }
202
203 if (!$notificationUserIds) {
204 return false;
205 }
206
207 as_schedule_single_action(time(), 'fluent_community/comment_added_async', [$comment->id, 0], 'fluent-community');
208 return true;
209 }
210
211 /*
212 * This is for the async notification for new comment
213 */
214 public function handleNewCommentNotificationAsync($commentId, $lastUserId = 0)
215 {
216 $comment = Comment::find($commentId);
217 if (!$comment) {
218 return true;
219 }
220
221 $feed = $comment->post;
222 if (!$feed) {
223 return;
224 }
225
226 if ($comment->parent_id) {
227 $globalCommentStatus = $this->isEnabled('reply_my_com_mail');
228 } else {
229 $globalCommentStatus = $this->isEnabled('com_my_post_mail');
230 }
231
232 $notificationUserIds = $comment->getCommentParentUserIds($lastUserId);
233 $notificationUserIds = array_filter($notificationUserIds, function ($userId) use ($globalCommentStatus) {
234 return NotificationPref::willGetCommentReplyEmail($userId, $globalCommentStatus);
235 });
236
237 $notificationUserIds = array_diff($notificationUserIds, [$comment->user_id]);
238 if ($comment->user_id != $feed->user_id && NotificationPref::willGetCommentEmail($feed->user_id, $globalCommentStatus)) {
239 // Add at the first
240 $notificationUserIds[] = $feed->user_id;
241 }
242
243 if (!$notificationUserIds) {
244 return;
245 }
246
247 if (!$notificationUserIds) {
248 return;
249 }
250
251 $notificationUserIds = array_unique($notificationUserIds);
252
253 $users = User::query()->whereIn('ID', $notificationUserIds)
254 ->whereHas('xprofile', function ($query) {
255 return $query->where('status', 'active');
256 })
257 ->when($lastUserId, function ($q) use ($lastUserId) {
258 $q->where('ID', '>', $lastUserId);
259 })
260 ->orderBy('ID', 'ASC')
261 ->get();
262
263 if ($users->isEmpty()) {
264 return; // it's done
265 }
266
267 $emailBody = $this->getCommentHtml($comment, true);
268 $emailSubject = $comment->getEmailSubject($feed);
269
270 $feedPermalik = $feed->getPermalink() . '?comment_id=' . $comment->id;
271 $usersCount = count($users);
272
273 $startTime = microtime(true);
274 $maxSendPerSecond = 10; // max 10 emails per second
275 foreach ($users as $index => $user) {
276 $lastUserId = $user->ID;
277 if ($user->ID == $comment->user_id) {
278 continue;
279 }
280
281 $newEmailBody = str_replace([
282 '##feed_permalink##',
283 '##email_notification_url##'
284 ], [
285 ProfileHelper::signUserUrlWithAuthHash($feedPermalik, $user->ID),
286 ProfileHelper::getSignedNotificationPrefUrl($user->ID)
287 ], $emailBody);
288
289 $mailer = new Mailer('', $emailSubject, $newEmailBody);
290 $mailer->to($user->user_email, $user->display_name);
291 $mailer->send();
292
293 if (microtime(true) - FLUENT_COMMUNITY_START_TIME > 50 && $index < ($usersCount - 1)) {
294 // It's been 45 seconds, let's stop and schedule the next one and schedule a new one
295 as_schedule_single_action(time(), 'fluent_community/comment_added_async', [$comment->id, $lastUserId], 'fluent-community');
296 return true;
297 }
298
299 if (($index + 1) % $maxSendPerSecond == 0) {
300 $timeTaken = microtime(true) - $startTime;
301 if ($timeTaken < 1) {
302 usleep(1000000 - ($timeTaken * 1000000));
303 }
304 $startTime = microtime(true);
305 }
306 }
307
308 // It's done
309 return true;
310 }
311
312 public function emailNotifyUsersForEveryoneTag($feedId, $lastSendUserId = 0)
313 {
314
315 if (!$this->maxRunTime) {
316 $this->maxRunTime = Utility::getMaxRunTime();
317 }
318
319 // Let's try to send email to all users of this space for this post
320 $feed = Feed::find($feedId);
321
322 if (!$feed || !$feed->space) {
323 return true;
324 }
325
326 $message = $feed->message;
327 $pattern = '/(?<!\S)@everyone(?!\S)/';
328
329 // match if the message contains @everyone
330 if (!preg_match($pattern, $message)) {
331 return true;
332 }
333
334 $notification = Notification::where('action', 'space_feed/created')
335 ->where('feed_id', $feed->id)
336 ->first();
337
338 if (!$notification) {
339 return true;
340 }
341
342 $users = User::whereDoesntHave('notificationSubscriptions', function ($query) {
343 $query->where('notification_type', 'mention_mail')
344 ->where('is_read', 0);
345 })
346 ->whereHas('space_pivot', function ($query) use ($feed) {
347 $query->where('space_id', $feed->space_id)
348 ->where('status', 'active');
349 })
350 ->whereHas('xprofile', function ($query) {
351 return $query->where('status', 'active');
352 })
353 ->orderBy('ID', 'ASC')
354 ->when($lastSendUserId, function ($q) use ($lastSendUserId) {
355 $q->where('ID', '>', $lastSendUserId);
356 })
357 ->limit(100)
358 ->get();
359
360 if ($users->isEmpty()) {
361 return true; // it's done
362 }
363
364 $author = $feed->user;
365 $emailSubject = \sprintf(
366 /* translators: %1$s is the user name, %2$s is the space title and %3$3s is the time */
367 __('%1$s mentioned you and others in a post at %2$s [%3$s]', 'fluent-community'),
368 $author->display_name,
369 $feed->space->title,
370 gmdate('H:i', strtotime($feed->created_at))
371 );
372 $emailBody = $this->getFeedHtml($feed, true);
373 $feedPermalink = $feed->getPermalink();
374
375 $startTime = microtime(true);
376 $maxSendPerSecond = 10; // max 10 emails per second
377
378 foreach ($users as $index => $user) {
379 $lastSendUserId = $user->ID;
380 if ($user->ID == $author->ID) {
381 continue;
382 }
383
384 $newEmailBody = str_replace([
385 '##feed_permalink##',
386 '##email_notification_url##'
387 ], [
388 ProfileHelper::signUserUrlWithAuthHash($feedPermalink, $user->ID),
389 ProfileHelper::getSignedNotificationPrefUrl($user->ID)
390 ], $emailBody);
391
392 $mailer = new Mailer('', $emailSubject, $newEmailBody);
393 $mailer->to($user->user_email, $user->display_name);
394 $mailer->send();
395
396 if (microtime(true) - FLUENT_COMMUNITY_START_TIME > $this->maxRunTime) {
397 // It's been 45 seconds, let's stop and schedule the next one and schedule a new one
398 as_schedule_single_action(time(), 'fluent_community/email_notify_users_everyone_tag', [$feedId, $lastSendUserId], 'fluent-community');
399 return true;
400 }
401
402 if (($index + 1) % $maxSendPerSecond == 0) {
403 $timeTaken = microtime(true) - $startTime;
404 if ($timeTaken < 1) {
405 usleep(1000000 - ($timeTaken * 1000000));
406 }
407 $startTime = microtime(true);
408 }
409 }
410
411 sleep(1); // sleeping for 1 second
412 return $this->emailNotifyUsersForEveryoneTag($feedId, $lastSendUserId);
413 }
414
415 public function getCommentHtml($comment, $withPlaceholder = false)
416 {
417 $emailComposer = new \FluentCommunity\App\Services\Libs\EmailComposer();
418 if ($withPlaceholder) {
419 $postPermalink = '##feed_permalink##';
420 } else {
421 $postPermalink = $comment->post->getPermalink() . '?comment_id=' . $comment->id;
422 }
423
424 if ($comment->post->title) {
425 $postTitle = $comment->post->title;
426 } else {
427 $postTitle = $comment->post->getHumanExcerpt(120);
428 }
429
430 $renderedMessage = $comment->message_rendered;
431
432 // Remove all the URLs with the text but make it underlined
433 $renderedMessage = preg_replace('/<a href="([^"]+)">([^<]+)<\/a>/', '<span style="text-decoration: underline !important;">$2</span>', $renderedMessage);
434
435 $renderedMessage .= $this->getMediaHtml($comment->meta, $postPermalink);
436
437 $emailComposer->addBlock('boxed_content', $renderedMessage, [
438 'user' => $comment->user,
439 'permalink' => $postPermalink,
440 'post_content' => $postTitle
441 ]);
442
443 $emailComposer->addBlock('button', __('View the comment', 'fluent-community'), [
444 'link' => $postPermalink
445 ]);
446
447 // $emailComposer->setLogo(\FluentCommunity\Framework\Support\Arr::get($settting, 'logo'));
448 $emailComposer->setDefaultFooter($withPlaceholder);
449
450 return $emailComposer->getHtml();
451 }
452
453 public function getFeedHtml($feed, $withPlaceholder = false)
454 {
455 $emailComposer = new \FluentCommunity\App\Services\Libs\EmailComposer();
456
457 if ($withPlaceholder) {
458 $postPermalink = '##feed_permalink##';
459 } else {
460 $postPermalink = $feed->getPermalink();
461 }
462
463 $feedHtml = $feed->message_rendered;
464 $feedHtml .= $this->getMediaHtml($feed->meta, $postPermalink);
465
466 $emailComposer->addBlock('post_boxed_content', $feedHtml, [
467 'user' => $feed->user,
468 'title' => $feed->title,
469 'permalink' => $postPermalink,
470 'space_name' => $feed->space ? $feed->space->title : __('Community', 'fluent-community'),
471 'is_single' => true
472 ]);
473
474 $emailComposer->addBlock('button', __('Join the conversation', 'fluent-community'), [
475 'link' => $postPermalink
476 ]);
477
478 // $emailComposer->setLogo(\FluentCommunity\Framework\Support\Arr::get($settting, 'logo'));
479 // $emailComposer->addFooterLine('paragraph', sprintf(__('You are getting this email because you are a member of %s', 'fluent-community'), '<a style="text-decoration: underline !important;" href="' . Helper::baseUrl() . '">' . get_bloginfo('name') . '</a>'));
480
481 $emailComposer->setDefaultFooter();
482
483 return $emailComposer->getHtml();
484 }
485
486 public function maybeSendDailyDigest()
487 {
488 if (!$this->maxRunTime) {
489 $this->maxRunTime = Utility::getMaxRunTime();
490 }
491
492 $settings = Utility::getEmailNotificationSettings();
493
494 $digestEmailDay = Arr::get($settings, 'digest_mail_day');
495 if (strtolower(gmdate('D', current_time('timestamp'))) != $digestEmailDay) {
496 return false;
497 }
498
499 $lastSentDate = Utility::getOption('last_digest_sent_date');
500 if ($lastSentDate && gmdate('Y-m-d', strtotime($lastSentDate)) == gmdate('Y-m-d', current_time('timestamp'))) {
501 return false; // already completed
502 }
503
504 $globalEnabled = Arr::get($settings, 'digest_email_status') === 'yes';
505 $lastSentUserId = Utility::getOption('last_digest_sent_user_id');
506
507 if ($globalEnabled) {
508 $users = User::whereDoesntHave('notification_records', function ($query) {
509 $query->where('notification_type', 'digest_mail')
510 ->where('is_read', 0);
511 })
512 ->whereHas('xprofile', function ($query) {
513 $query->where('status', 'active');
514 })
515 ->when($lastSentUserId, function ($q) use ($lastSentUserId) {
516 $q->where('ID', '>', $lastSentUserId);
517 })
518 ->limit(100)
519 ->orderBy('ID', 'ASC')
520 ->get();
521 } else {
522 $users = User::whereHas('notification_records', function ($query) {
523 $query->where('notification_type', 'digest_mail')
524 ->where('is_read', 1);
525 })
526 ->orderBy('ID', 'ASC')
527 ->whereHas('xprofile', function ($query) {
528 return $query->where('status', 'active');
529 })
530 ->when($lastSentUserId, function ($q) use ($lastSentUserId) {
531 $q->where('ID', '>', $lastSentUserId);
532 })
533 ->limit(100)
534 ->get();
535 }
536
537 if ($users->isEmpty()) {
538 // It's done
539 Utility::updateOption('last_digest_sent_date', current_time('mysql'));
540 Utility::updateOption('last_digest_sent_user_id', 0);
541 return false;
542 }
543
544 $startAt = microtime(true);
545 $maxSendPerSecond = 10;
546
547 $sentCount = 0;
548
549 foreach ($users as $user) {
550 Utility::updateOption('last_digest_sent_user_id', $user->user_id);
551 $emailDigest = new DailyDigest($user);
552 if ($emailDigest->send()) {
553 $sentCount++;
554 }
555
556 if (microtime(true) - FLUENT_COMMUNITY_START_TIME > $this->maxRunTime) {
557 // It's been 45 seconds, let's stop and schedule the next one and schedule a new one
558 as_schedule_single_action(time(), 'fluent_community_send_daily_digest', [], 'fluent-community', false);
559 return true;
560 }
561
562 if ($sentCount % $maxSendPerSecond === 0) {
563 $timeTaken = microtime(true) - $startAt;
564 if ($timeTaken < 1) {
565 usleep(1000000 - ($timeTaken * 1000000));
566 }
567 $startAt = microtime(true);
568 }
569 }
570
571 return $this->maybeSendDailyDigest();
572 }
573
574 private function isEnabled($key)
575 {
576 $settings = Utility::getEmailNotificationSettings();
577
578 return Arr::get($settings, $key) === 'yes';
579 }
580
581 public function handleCommunityJoinRequest(BaseSpace $space, $userId)
582 {
583 $xProfile = XProfile::where('user_id', $userId)->first();
584 if (!$xProfile) {
585 return;
586 }
587
588 $settting = Helper::generalSettings();
589
590 $emailComposer = new \FluentCommunity\App\Services\Libs\EmailComposer();
591
592 $emailComposer->addBlock('paragraph', __('Hi Space Leader,', 'fluent-community'));
593 $emailComposer->addBlock('paragraph', sprintf(__('You have a new join request from %1$s to join %2$s.', 'fluent-community'), '<b>' . $xProfile->display_name . '</b>', '<b>' . $space->title . '</b>'));
594 $emailComposer->addBlock('paragraph', __('Please review the request in the portal', 'fluent-community'));
595
596 $emailComposer->addBlock('button', __('View Pending Join Requests', 'fluent-community'), [
597 'link' => Helper::baseUrl('space/' . $space->slug . '/members?view_pending=yes')
598 ]);
599
600 $emailComposer->setLogo(\FluentCommunity\Framework\Support\Arr::get($settting, 'logo'));
601
602 $emailComposer->addFooterLine('paragraph', sprintf(__('You are getting this email because you are an admin/moderator at %s', 'fluent-community'), '<a style="text-decoration: underline !important;" href="' . $space->getPermalink() . '">' . $space->title . '</a>'));
603
604 $emailBody = $emailComposer->getHtml();
605
606 $emailSubject = \sprintf(
607 __('%1$s requested to join %2$s', 'fluent-community'),
608 $xProfile->display_name,
609 $space->title
610 );
611
612 $moderatorsUserIds = SpaceUserPivot::where('space_id', $space->id)
613 ->whereIn('role', ['moderator', 'admin'])
614 ->pluck('user_id')
615 ->toArray();
616
617 if (!$moderatorsUserIds) {
618 return false;
619 }
620
621 $mailer = new Mailer('', $emailSubject, $emailBody);
622 if (count($moderatorsUserIds) == 1) {
623 $modUserId = $moderatorsUserIds[0];
624
625 $moderator = get_user_by('ID', $modUserId);
626
627 if (!$moderator || !$moderator->user_email) {
628 return;
629 }
630
631 $mailer->to($moderator->user_email, $moderator->display_name);
632 return $mailer->send();
633 }
634
635 // send by BCC by 12 chunks
636 $chunks = array_chunk($moderatorsUserIds, 12);
637
638 foreach ($chunks as $chunk) {
639
640 $mailer = new Mailer('', $emailSubject, $emailBody);
641
642 $users = User::whereIn('ID', $chunk)->get();
643 foreach ($users as $user) {
644 if (!$user || !$user->user_email) {
645 continue;
646 }
647 $mailer->addBCC($user->display_name . ' <' . $user->user_email . '>');
648 }
649
650 $mailer->send();
651 sleep(1); // sleeping for 1 second
652 }
653
654 return true;
655 }
656
657 private function getMediaHtml($meta, $postPermalink)
658 {
659 $mediaImage = Arr::get($meta, 'media_preview.image');
660 $mediaCount = 0;
661 if (!$mediaImage) {
662 $mediaItems = Arr::get($meta, 'media_items', []);
663 if ($mediaItems) {
664 $mediaImage = Arr::get($mediaItems[0], 'url');
665 $mediaCount = count($mediaItems);
666 }
667 }
668
669 $feedHtml = '';
670
671 if ($mediaImage) {
672 $feedHtml .= '<div class="fcom_media" style="margin-top: 20px;">';
673 $feedHtml .= '<a href="' . $postPermalink . '"><img src="' . $mediaImage . '" style="max-width: 100%; height: auto; display: block; margin: 0 auto 0px;" /></a>';
674 if ($mediaCount > 1) {
675 $feedHtml .= '<p style="text-align: center; font-size: 14px; color: #666; margin-top: 10px;">' . sprintf(_n('+%d more image', '+%d more images', $mediaCount - 1, 'fluent-community'), $mediaCount - 1) . '</p>';
676 }
677 $feedHtml .= '</div>';
678 }
679
680 return $feedHtml;
681 }
682 }
683