← All changes
|
Modules/PushNotification/PushNotificationModule.php
+118
-23
2.8.0
→
2.10.0
View file →
| @@ -1,28 +1,104 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace FluentCommunity\Modules\PushNotification; |
| 4 | 4 | |
| 5 | +use FluentCommunity\App\Functions\Utility; | |
| 5 | 6 | use FluentCommunity\App\Services\Helper; |
| 7 | +use FluentCommunity\App\Services\NotificationPref; | |
| 6 | 8 | use FluentCommunity\Framework\Support\Arr; |
| 7 | 9 | |
| 8 | 10 | class PushNotificationModule |
| 9 | 11 | { |
| 12 | + const SETUP_NOT_INSTALLED = 'not_installed'; | |
| 13 | + const SETUP_INACTIVE = 'inactive'; | |
| 14 | + const SETUP_DISABLED = 'disabled'; | |
| 15 | + const SETUP_INCOMPLETE = 'incomplete'; | |
| 16 | + const SETUP_READY = 'ready'; | |
| 17 | + | |
| 18 | + const PROMPT_PLACEMENTS = ['feed_sidebar','profile_notification_prefs','profile_sidebar','notification_popover']; | |
| 19 | + | |
| 20 | + const COMMENT_ACTIONS = [ | |
| 21 | + 'fluent_community/notification/comment/notifed_to_author', | |
| 22 | + 'fluent_community/notification/comment/notifed_to_mentions', | |
| 23 | + 'fluent_community/notification/comment/notifed_to_thread_commetenter', | |
| 24 | + 'fluent_community/notification/comment/notifed_to_other_users' | |
| 25 | + ]; | |
| 26 | + | |
| 27 | + const PUSHED_ACTIONS = ['comment_added', 'child_comment_added', 'mention_added']; | |
| 28 | + | |
| 29 | + public static function isFluentNotifyActive() | |
| 30 | + { | |
| 31 | + return self::getSetupState() === self::SETUP_READY; | |
| 32 | + } | |
| 33 | + | |
| 34 | + /** | |
| 35 | + * Which step of the FluentNotify setup is still outstanding, so the settings | |
| 36 | + * screen can say what to do rather than only that something is missing. | |
| 37 | + * | |
| 38 | + * @return string One of the SETUP_* constants. | |
| 39 | + */ | |
| 40 | + public static function getSetupState() | |
| 41 | + { | |
| 42 | + if (!defined('FLUENT_NOTIFY_PLUGIN_VERSION')) { | |
| 43 | + // The files can be there while the plugin is deactivated, which needs | |
| 44 | + // activating rather than another download. | |
| 45 | + if (file_exists(WP_PLUGIN_DIR . '/fluent-notify/fluent-notify.php')) { | |
| 46 | + return self::SETUP_INACTIVE; | |
| 47 | + } | |
| 48 | + | |
| 49 | + return self::SETUP_NOT_INSTALLED; | |
| 50 | + } | |
| 51 | + | |
| 52 | + if (!\FluentNotify\App\Services\Helper::isEnabled()) { | |
| 53 | + return self::SETUP_DISABLED; | |
| 54 | + } | |
| 55 | + | |
| 56 | + if (!\FluentNotify\App\Services\Helper::isConfigComplete()) { | |
| 57 | + return self::SETUP_INCOMPLETE; | |
| 58 | + } | |
| 59 | + | |
| 60 | + return self::SETUP_READY; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public static function getSettingsUrl() | |
| 64 | + { | |
| 65 | + // FluentNotify picks hash or history routing at runtime; the fragment is | |
| 66 | + // ignored under history routing, which lands on its dashboard instead. | |
| 67 | + return admin_url('admin.php?page=fluent-notify#/settings'); | |
| 68 | + } | |
| 69 | + | |
| 70 | + public static function isAvailable() | |
| 71 | + { | |
| 72 | + $pushEnabledInCommunity = Arr::get(Utility::getPushNotificationSettings(), 'push_enabled') === 'yes'; | |
| 73 | + | |
| 74 | + return self::isFluentNotifyActive() && $pushEnabledInCommunity; | |
| 75 | + } | |
| 76 | + | |
| 77 | + public static function getPushedCommentIds($userId, $commentIds) | |
| 78 | + { | |
| 79 | + if (!$userId || !$commentIds || !class_exists('\FluentNotify\App\Models\NotificationLog')) { | |
| 80 | + return []; | |
| 81 | + } | |
| 82 | + | |
| 83 | + $pushed = \FluentNotify\App\Models\NotificationLog::query() | |
| 84 | + ->join('fn_subscriptions', 'fn_subscriptions.id', '=', 'fn_notifications.subscription_id') | |
| 85 | + ->where('fn_subscriptions.user_id', $userId) | |
| 86 | + ->where('fn_notifications.source', 'community_comment') | |
| 87 | + ->whereIn('fn_notifications.source_id', $commentIds) | |
| 88 | + ->whereNotIn('fn_notifications.status', ['fcm_failed', 'fcm_skipped']) | |
| 89 | + ->pluck('fn_notifications.source_id') | |
| 90 | + ->toArray(); | |
| 91 | + | |
| 92 | + return array_values(array_unique(array_map('intval', $pushed))); | |
| 93 | + } | |
| 94 | + | |
| 10 | 95 | public function register() |
| 11 | 96 | { |
| 12 | - if (!defined('FLUENT_NOTIFY_PLUGIN_VERSION') || !\FluentNotify\App\Services\Helper::isEnabled()) { | |
| 13 | - return; | |
| 14 | - } | |
| 97 | + if (!self::isAvailable()) return; | |
| 15 | 98 | |
| 16 | - $commentActions = [ | |
| 17 | - 'fluent_community/notification/comment/notifed_to_author', | |
| 18 | - // 'fluent_community/notification/comment/notifed_to_author', | |
| 19 | - 'fluent_community/notification/comment/notifed_to_mentions', | |
| 20 | - //'fluent_community/notification/comment/notifed_to_other_users', | |
| 21 | - 'fluent_community/notification/comment/notifed_to_thread_commetenter', | |
| 22 | - ]; | |
| 23 | - foreach ($commentActions as $action) { | |
| 24 | - add_action($action, [ $this, 'handleCommentNotification' ], 10, 1); | |
| 99 | + foreach (self::COMMENT_ACTIONS as $action) { | |
| 100 | + add_action($action, [$this, 'handleCommentNotification'], 10, 1); | |
| 25 | 101 | } |
| 26 | 102 | |
| 27 | 103 | // let's load the assets |
| 28 | 104 | add_filter('fluent_community/portal_data_vars', function ($vars) { |
| @@ -44,8 +120,9 @@ | ||
| 44 | 120 | return $vars; |
| 45 | 121 | } |
| 46 | 122 | |
| 47 | 123 | $vars['has_push_notification'] = true; |
| 124 | + $vars['push_prompt_placements'] = Arr::get(Utility::getPushNotificationSettings(), 'prompt_placements'); | |
| 48 | 125 | |
| 49 | 126 | return $vars; |
| 50 | 127 | }); |
| 51 | 128 | |
| @@ -56,18 +133,33 @@ | ||
| 56 | 133 | $key = Arr::get($eventData, 'key'); |
| 57 | 134 | $comment = Arr::get($eventData, 'comment'); |
| 58 | 135 | $feed = Arr::get($eventData, 'feed'); |
| 59 | 136 | |
| 137 | + if (!$feed || !$comment) return; | |
| 138 | + | |
| 139 | + // Hook event key => notification event in NotificationPref::NOTIFICATION_EVENTS. | |
| 140 | + $hookToEvent = [ | |
| 141 | + 'notifed_to_author' => 'comment', | |
| 142 | + 'notifed_to_thread_commetenter' => 'reply', | |
| 143 | + 'notifed_to_mentions' => 'mention', | |
| 144 | + 'notifed_to_other_users' => 'co_comment' | |
| 145 | + ]; | |
| 146 | + | |
| 147 | + $userIds = NotificationPref::filterPushUserIds( | |
| 148 | + Arr::get($eventData, 'user_ids', []), | |
| 149 | + Arr::get($hookToEvent, $key, '') | |
| 150 | + ); | |
| 151 | + | |
| 152 | + if (!$userIds) return; | |
| 153 | + | |
| 60 | 154 | $xprofile = $comment->xprofile; |
| 61 | 155 | |
| 62 | - if (!$feed || !$comment) { | |
| 63 | - return; | |
| 64 | - } | |
| 65 | - | |
| 66 | 156 | $notification = Arr::get($eventData, 'notification'); |
| 67 | - $content = Helper::getHumanExcerpt($comment->message, 100); | |
| 157 | + $content = Helper::getHumanExcerpt($comment->message_rendered ?: $comment->message, 100); | |
| 68 | 158 | if (!$content) { |
| 69 | - $content = Helper::getHumanExcerpt($notification->content, 100); | |
| 159 | + // The co-comment hook passes the notification as an array, the others as a model. | |
| 160 | + $fallback = is_array($notification) ? Arr::get($notification, 'content') : $notification->content; | |
| 161 | + $content = Helper::getHumanExcerpt($fallback, 100); | |
| 70 | 162 | } |
| 71 | 163 | |
| 72 | 164 | $commenter = $xprofile ? $xprofile->display_name : '' . __('Someone', 'fluent-community'); |
| 73 | 165 | $feedTitle = $feed->title ? $feed->title : __('post', 'fluent-community'); |
| @@ -81,9 +173,9 @@ | ||
| 81 | 173 | $title = ''; |
| 82 | 174 | switch ($key): |
| 83 | 175 | case 'notifed_to_author': |
| 84 | 176 | /* translators: %1$s is the commenter name, %2$s is the post title */ |
| 85 | - $title = \sprintf(__('💬 by %1$s: %2$s', 'fluent-community'), $commenter, $feedTitle); | |
| 177 | + $title = \sprintf(__('New comment by %1$s on: %2$s', 'fluent-community'), $commenter, $feedTitle); | |
| 86 | 178 | break; |
| 87 | 179 | case 'notifed_to_mentions': |
| 88 | 180 | /* translators: %1$s is the commenter name, %2$s is the post title */ |
| 89 | 181 | $title = \sprintf(__('%1$s mentioned you on: %2$s', 'fluent-community'), $commenter, $feedTitle); |
| @@ -89,9 +181,9 @@ | ||
| 89 | 181 | $title = \sprintf(__('%1$s mentioned you on: %2$s', 'fluent-community'), $commenter, $feedTitle); |
| 90 | 182 | break; |
| 91 | 183 | case 'notifed_to_other_users': |
| 92 | 184 | /* translators: %1$s is the commenter name, %2$s is the post title */ |
| 93 | - $title = \sprintf(__('New comment by %1$s on: %2$s', 'fluent-community'), $commenter, $feedTitle); | |
| 185 | + $title = \sprintf(__('%1$s also commented on: %2$s', 'fluent-community'), $commenter, $feedTitle); | |
| 94 | 186 | break; |
| 95 | 187 | case 'notifed_to_thread_commetenter': |
| 96 | 188 | /* translators: %1$s is the commenter name, %2$s is the post title */ |
| 97 | 189 | $title = \sprintf(__('%1$s replied to a comment on: %2$s', 'fluent-community'), $commenter, $feedTitle); |
| @@ -100,16 +192,19 @@ | ||
| 100 | 192 | /* translators: %1$s is the commenter name, %2$s is the post title */ |
| 101 | 193 | $content = \sprintf(__('Comment by %1$s on %2$s', 'fluent-community'), $commenter, $feedTitle); |
| 102 | 194 | endswitch; |
| 103 | 195 | |
| 104 | - $userIds = Arr::get($eventData, 'user_ids', []); | |
| 105 | - $feedPermalik = $feed->getPermalink() . '?comment_id=' . $comment->id; | |
| 196 | + $actionUrl = add_query_arg([ | |
| 197 | + 'comment_id' => $comment->id, | |
| 198 | + 'fcom_pn' => 'true', | |
| 199 | + 'feed_id' => $feed->id, | |
| 200 | + ], $feed->getPermalink()); | |
| 106 | 201 | |
| 107 | 202 | do_action('fluent_notify/schedule_notifications', $userIds, [ |
| 108 | 203 | 'user_ids' => $userIds, |
| 109 | 204 | 'title' => $title, |
| 110 | 205 | 'message' => $content, |
| 111 | - 'action_url' => $feedPermalik, | |
| 206 | + 'action_url' => $actionUrl, | |
| 112 | 207 | 'icon' => $xprofile->avatar, |
| 113 | 208 | 'source' => 'community_comment', |
| 114 | 209 | 'source_id' => $comment->id, |
| 115 | 210 | ]); |