Выбор отдельных уведомлений и подготовка более четкого уведомления

Я создал систему уведомлений, и это очень хорошо. Есть несколько вещей, над которыми нужно работать, чтобы сделать их идеальными – вот и я.

Приложение, над которым я работаю, – это сайт, написанный на PHP.

В моих уведомлениях есть столбец, который указывает, было ли уведомление отправлено или нет. Этот столбец обновляется, когда пользователь нажимает кнопку раскрывающегося списка уведомлений, которая очень похожа на Facebook.

Есть несколько случаев, когда есть два одинаковых уведомления – один и тот же пользователь с той же целью (URL). Я хочу, чтобы уведомления были выбраны уникальным способом, а те же, которые нужно игнорировать. Я даже не могу понять, как эти идентичные хранятся в первую очередь.

В любом случае, вот пример массива уведомлений:

 Array ( [0] => Array ( [notification_id] => 34 [receiver_id] => 9 [notification_issuer] => 11 [notification_message] => Dugipo has liked your image [notification_target] => http://localhost/imgzer/image/v2M6S2V1J3h7 [notification_type] => like [notification_time] => 1391291043 [notification_seen] => 1 [user_avatar] => [username] => Dugipo ) [1] => Array ( [notification_id] => 33 [receiver_id] => 9 [notification_issuer] => 11 [notification_message] => Dugipo has liked your image [notification_target] => http://localhost/imgzer/image/v2M6S2V1J3h7 [notification_type] => like [notification_time] => 1391288815 [notification_seen] => 1 [user_avatar] => [username] => Dugipo ) [2] => Array ( [notification_id] => 32 [receiver_id] => 9 [notification_issuer] => 11 [notification_message] => Dugipo has liked your comment [notification_target] => http://localhost/imgzer/image/o3F6g8b8t6Q0#cid-64 [notification_type] => like [notification_time] => 1391216243 [notification_seen] => 1 [user_avatar] => [username] => Dugipo ) [3] => Array ( [notification_id] => 31 [receiver_id] => 9 [notification_issuer] => 11 [notification_message] => Dugipo has liked your image [notification_target] => http://localhost/imgzer/image/o3F6g8b8t6Q0 [notification_type] => like [notification_time] => 1391216135 [notification_seen] => 1 [user_avatar] => [username] => Dugipo ) [4] => Array ( [notification_id] => 30 [receiver_id] => 9 [notification_issuer] => 11 [notification_message] => Dugipo has liked your image [notification_target] => http://localhost/imgzer/image/o3F6g8b8t6Q0 [notification_type] => like [notification_time] => 1391214642 [notification_seen] => 1 [user_avatar] => [username] => Dugipo ) ) 

Как вы можете видеть, есть две пары одинаковых массивов, и это не то, что мне нужно. Я также пытаюсь добиться эффекта, когда двум или более людям нравится одно и то же, сообщения становятся такими: X, Y и n другим понравилось ваше изображение

Я не могу думать о том, как я это сделаю. Во всяком случае, это функция / метод, который собирает уведомления:

 public function getNotifications($seen = false) { global $db; $seen = ($seen === true) ? 1 : 0; $limit = ($seen === true) ? 5 : 10; $sql = 'SELECT n.*, u.user_avatar, u.username FROM ' . NOTIFICATIONS_TABLE . ' n LEFT JOIN ' . USERS_TABLE . " u ON n.notification_issuer = u.user_id WHERE receiver_id = ? AND notification_seen = $seen ORDER BY notification_time DESC LIMIT 5"; $query = $db->prepare($sql); $query->execute(array($this->id)); $result = $query->fetchAll(PDO::FETCH_ASSOC); /*for ($i = 0; $i < sizeof($result); $i++) { if ($result[$i]['notification_message'] == $result[++$i]['notification_message']) { $new_message = ''; if ($result[$i]['notification_issuer'] != $result[++$i]['notification_issuer']) { $new_message .= ''; } } }*/ return $result; } 

Прокомментированный цикл должен был создать тот эффект, когда люди, которые любили определенную вещь, стали единственным уведомлением, а имена разделяются запятой и «и» для других людей, которым понравился образ.

Это функция / метод, который хранит уведомления:

 public function sendNotification($notification, $receiver, $notification_target = null, $notification_type = 'default') { global $db; $sql = 'INSERT INTO ' . NOTIFICATIONS_TABLE . '(receiver_id, notification_issuer, notification_message, notification_target, notification_type, notification_time) VALUES (?, ?, ?, ?, ?, ?)'; $query = $db->prepare($sql); $query->execute(array($receiver, $this->id, $notification, $notification_target, $notification_type, time())); } 

Пример использования этого метода:

 // Send notification / Make sure that the notification sender isn't the same user that's going to receive the notification if ($user->get_data('user_id') != $this->image_uploader_id) { $user->sendNotification( sprintf('<strong>%s</strong> has liked your image', $user->get_data('username')), $this->image_uploader_id, self::convert('name2url', $this->image_name), 'like' ); } 

Наконец, вот схема таблицы уведомлений:

 +----------------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------------+---------------------+------+-----+---------+----------------+ | notification_id | int(11) unsigned | NO | PRI | NULL | auto_increment | | receiver_id | int(11) unsigned | NO | | NULL | | | notification_issuer | int(11) unsigned | NO | | NULL | | | notification_message | varchar(255) | NO | | NULL | | | notification_target | varchar(255) | YES | | NULL | | | notification_type | varchar(55) | NO | | default | | | notification_time | int(11) unsigned | NO | | NULL | | | notification_seen | tinyint(1) unsigned | NO | | 0 | | +----------------------+---------------------+------+-----+---------+----------------+ 

SQL Fiddle: http://www.sqlfiddle.com/#!2/6970b/1


Поэтому я в основном после двух вещей здесь:

  1. Уметь выбирать уникальные строки. Повторяющиеся строки игнорируются
  2. Получите эффект, чтобы объединить уведомления, которые имеют одну и ту же цель, к одному уведомлению, которое затем показывает имена лиц одного и того же действия (например, нравится) следующим образом: X, Y, Z и другим понравилось ваше изображение.

Поэтому после SELECT из базы данных я хотел бы, чтобы все пользователи, которые создали уведомление для одной и той же цели, стали хорошо читаемой строкой, как я описал выше. Я стараюсь, чтобы пользователи, которые любили / не любили / комментировали одну и ту же цель, имели отдельное уведомление получателю – они должны каким-то образом конкатенироваться.

Итак, скажем, действие похоже на изображение . Пять пользователей image_like-d тот же notification_target или теперь мы можем определить, о чем пользователь получит уведомление с notification_type (который будет image_like ) и reference_id (мы узнаем, что это будет изображение сейчас); Итак, теперь у нас есть полное представление о том, что нравится image_id на основе reference_id и мы также знаем, что это образ, потому что notification_type говорит об изображении _like.

Итак, с этой таблицей:

 id reference target issuer_id type 1 25 tg1 43 like 2 25 tg1 23 like 3 53 tg2 77 comment 4 53 tg2 23 comment 5 53 tg2 67 comment 6 53 tg2 98 dislike 7 34 tg3 65 like 

Из этой таблицы это будут следующие результаты:

  • User43 и User23 понравились reference25 (ссылки на tg1)
  • User77, User23 и User67 прокомментировали ссылку 53 (ссылки на tg2)
  • User98 не понравился reference53 (ссылки на tg2)
  • Пользователь65 понравился reference34 (ссылки на tg3)

Любая помощь будет оценена по достоинству.

Related of "Выбор отдельных уведомлений и подготовка более четкого уведомления"

Я использую только часть запроса, которая решает ваши первые и второй требования, предполагая, что ваши данные остаются в одной структуре. Вы можете добавить в свой запрос соединения и другие необходимые данные.

SELECT myView.*, CONCAT(REPLACE(REPLACE(group_concat(SUBSTRING(notification_message,9)),'</strong>',''),SUBSTRING_INDEX(notification_message,'>',-1),''), SUBSTRING_INDEX(notification_message,'>',-1)) AS Message
FROM (SELECT DISTINCT receiver_id, notification_issuer, notification_message, notification_target, notification_type FROM imgzer_notifications
WHERE receiver_id = 9 and notification_seen = 1 ORDER BY notification_time DESC) myView GROUP BY myView.receiver_id, myView.notification_target, myView.notification_type;

Я знаю, что функции String выглядят сложными, но чтобы достичь нужного результата, пришлось поиграть со строками. Я немного изменил свой набор данных в SQL Fiddle, чтобы проверить свой вывод. Вы можете сделать то же самое:

http://www.sqlfiddle.com/#!2/70a937/49

Сообщите мне, если есть какие-то другие критерии, которые необходимо выполнить, или любое усовершенствование, которое требуется в запросе.

Сделав много предположений о ваших данных, примерно так:

 public function getNotifications($seen = false) { global $db; $new_message = ''; $seen = ($seen === true) ? 1 : 0; $limit = ($seen === true) ? 5 : 10; $sql = 'SELECT n.receiver_id, n.notification_type, GROUP_CONCAT(DISTINCT CONCAT_WS(':', u.username, u.user_avatar)) AS msgs, MAX(n.notification_time) AS LatestTime FROM ' . NOTIFICATIONS_TABLE . ' n LEFT OUTER JOIN' . USERS_TABLE . " u ON n.notification_issuer = u.user_id WHERE receiver_id = ? AND notification_seen = $seen GROUP BY n.receiver_id, n.notification_type ORDER BY LatestTime DESC LIMIT $limit"; $query = $db->prepare($sql); $query->execute(array($this->id)); while ($row = $query->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT)) { $notif = explode(',', $row['msgs']); switch (count($notif)) { case 0 : // Should never happen break; case 1 : $aNotif = explode(":", $notif[0]); $new_message .= "<img='".$aNotif[1]."' />".$aNotif[0]." has ".$row['notification_type']." your event."; break; default : foreach($notif AS $key=>$oneNotif) { $aNotif = explode(":", $oneNotif); switch ($key) { case 0: $new_message .= "<img='".$aNotif[1]."' />".$aNotif[0]; break; case (count($notif) - 1): $new_message .= " and <img='".$aNotif[1]."' />".$aNotif[0]; break; default: $new_message .= ", <img='".$aNotif[1]."' />".$aNotif[0]; break; } } $new_message .= " has ".$row['notification_type']." your event by ".$row['LatestTime']."."; break; } } return $new_message; } 

Проблема в том, что время уведомления не используется (не знаю, где я буду использовать последний), не уверен, что вы хотите делать с изображениями (я догадался, но, вероятно, неправильно), и несколькими другими второстепенными битами.

РЕДАКТИРОВАТЬ

SQL для того, что я думаю, что вы сейчас хотите.

Это дает вам все уведомления (для получателя и видно или не видно), для последних 5 ссылок есть уведомление.

 SELECT n.reference_id, GROUP_CONCAT(n.notification_message) AS msgs FROM ' . NOTIFICATIONS_TABLE . ' n INNER JOIN ( SELECT receiver_id, notification_seen, reference_id, notification_issuer, MAX(notification_time) as max_notification_time FROM ' . NOTIFICATIONS_TABLE . ' WHERE receiver_id = ? AND notification_seen = ? GROUP BY receiver_id, notification_seen, reference_id, notification_issuer ) Sub1 ON n.receiver_id = Sub1.receiver_id AND nnotification_seen = Sub1.notification_seen AND n.reference_id = Sub1.reference_id AND n.notification_issuer = Sub1.notification_issuer AND n.notification_time = Sub1.max_notification_time GROUP BY n.reference_id ORDER BY reference_id, notification_time DESC LIMIT $limit 

EDIT снова

Используя последние обновленные данные, этот SQL будет делать это: –

 SELECT n.receiver_id, n.reference_id, n.notification_type, CONCAT_WS(' ', GROUP_CONCAT(u.user_name), n.notification_type, n.reference_id) AS msgs, MAX(max_notification_id) as max_max_notification_id FROM imgzer_notifications n INNER JOIN ( SELECT receiver_id, reference_id, notification_issuer, notification_type, MAX(notification_id) as max_notification_id FROM imgzer_notifications WHERE receiver_id = ? AND notification_seen = ? GROUP BY receiver_id, reference_id, notification_issuer, notification_type ) Sub1 ON n.receiver_id = Sub1.receiver_id AND n.reference_id = Sub1.reference_id AND n.notification_issuer = Sub1.notification_issuer AND n.notification_id = Sub1.max_notification_id AND n.notification_type = Sub1.notification_type INNER JOIN imgzer_users u ON n.notification_issuer = u.user_id GROUP BY receiver_id, n.reference_id, n.notification_type ORDER BY max_max_notification_id DESC LIMIT $limit 

Сообщение – беспорядок, хотя (последняя запятая между эмитентами уведомлений не заменяется на и, и она должна изменить «как» на «понравилась» и т. Д.).

Что это делает, так это получение последнего уведомления для каждого эмитента уведомлений для каждой ссылки. Затем присоединяется к уведомлениям, чтобы получить остальную информацию, и использует GROUP_CONCAT для объединения их в одну строку для конкретной ссылки и типа уведомления. CONCAT_WS используется для добавления типа уведомления и любого постоянного текста, и он упорядочен по наивысшему максимальному идентификатору уведомления, опускающемуся из подзапроса. Таким образом, это типы ссылок / уведомлений, которые содержат последнее уведомление, которое указано первым (даже если некоторые уведомления в этом сообщении не так уж и свежие).

SQL скрипта для этой настройки здесь: –

http://www.sqlfiddle.com/#!2/4d876/1