Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL][PHP] Pobranie nieprzeczytanych wiadomości użytkownika
gogomania
post
Post #1





Grupa: Zarejestrowani
Postów: 51
Pomógł: 1
Dołączył: 7.02.2013

Ostrzeżenie: (0%)
-----


Witam,
próbuję stworzyć zapytanie, które pobierze wiadomości obecnie zalogowanego użytkownika.

Struktura tabel:
  1. CREATE TABLE `konwersacje` (
  2. `konwersacja_id` int(8) NOT NULL,
  3. `konwersacja_temat` varchar(150) NOT NULL
  4. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  5. ALTER TABLE `konwersacje`
  6. ADD PRIMARY KEY (`konwersacja_id`);
  7. ALTER TABLE `konwersacje`
  8. MODIFY `konwersacja_id` int(8) NOT NULL AUTO_INCREMENT;
  9.  
  10. CREATE TABLE `konwersacje_czlonkowie` (
  11. `id` int(11) NOT NULL,
  12. `konwersacja_id` int(8) NOT NULL,
  13. `uzytkownik_id` int(11) NOT NULL,
  14. `konwersacja_ostatnio_ogladana` int(10) NOT NULL,
  15. `konwersacja_usunieta` int(1) NOT NULL
  16. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  17. ALTER TABLE `konwersacje_czlonkowie`
  18. ADD PRIMARY KEY (`id`),
  19. ADD UNIQUE KEY `unikalny` (`konwersacja_id`,`uzytkownik_id`),
  20. ADD KEY `FK_uzytkownicy_konwersacje_czlonkowie1` (`uzytkownik_id`);
  21. ALTER TABLE `konwersacje_czlonkowie`
  22. MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
  23. ALTER TABLE `konwersacje_czlonkowie`
  24. ADD CONSTRAINT `FK_uzytkownicy_konwersacje_czlonkowie1` FOREIGN KEY (`uzytkownik_id`) REFERENCES `uzytkownicy` (`uzytkownik_id`) ON UPDATE CASCADE;
  25.  
  26. CREATE TABLE `konwersacje_wiadomosci` (
  27. `wiadomosc_id` int(10) NOT NULL,
  28. `konwersacja_id` int(8) NOT NULL,
  29. `uzytkownik_id` int(11) NOT NULL,
  30. `data_wyslania` int(10) NOT NULL,
  31. `wiadomosc_ogladana` int(1) NOT NULL DEFAULT '0',
  32. `wiadomosc_tresc` text NOT NULL
  33. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  34. ALTER TABLE `konwersacje_wiadomosci`
  35. ADD PRIMARY KEY (`wiadomosc_id`),
  36. ADD KEY `konwersacja_id` (`konwersacja_id`),
  37. ADD KEY `uzytkownik_id` (`uzytkownik_id`);
  38. ALTER TABLE `konwersacje_wiadomosci`
  39. MODIFY `wiadomosc_id` int(10) NOT NULL AUTO_INCREMENT;
  40. ALTER TABLE `konwersacje_wiadomosci`
  41. ADD CONSTRAINT `FK_uzytkownicy_konwersacje_wiadomosci` FOREIGN KEY (`uzytkownik_id`) REFERENCES `uzytkownicy` (`uzytkownik_id`) ON UPDATE CASCADE;
  42.  
  43. CREATE TABLE `uzytkownicy` (
  44. `uzytkownik_id` int(11) NOT NULL,
  45. `login` varchar(32) NOT NULL,
  46. `haslo` varchar(255) NOT NULL,
  47. `imie` varchar(55) NOT NULL,
  48. `nazwisko` varchar(80) NOT NULL,
  49. `tel_komorkowy` varchar(25) NOT NULL DEFAULT '',
  50. `tel_stacjonarny` varchar(25) NOT NULL DEFAULT '',
  51. `email` varchar(200) NOT NULL,
  52. `firma_id` int(1) NOT NULL DEFAULT '0',
  53. `pozwol_email` int(1) NOT NULL DEFAULT '0',
  54. `uprawnienia` int(1) NOT NULL DEFAULT '0',
  55. `ostatnie_logowanie` datetime DEFAULT NULL,
  56. `zdjecie` varchar(150) DEFAULT NULL,
  57. `typ` enum('Normalny','Pracownik','Administrator','Super-Administrator') NOT NULL DEFAULT 'Normalny',
  58. `aktywny` int(1) NOT NULL DEFAULT '0'
  59. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  60. ALTER TABLE `uzytkownicy`
  61. ADD PRIMARY KEY (`uzytkownik_id`),
  62. ADD UNIQUE KEY `login` (`login`),
  63. ADD KEY `firma_id` (`firma_id`);
  64. ALTER TABLE `uzytkownicy`
  65. MODIFY `uzytkownik_id` int(11) NOT NULL AUTO_INCREMENT;
  66. ALTER TABLE `uzytkownicy`
  67. ADD CONSTRAINT `FK_firmy_uzytkownicy` FOREIGN KEY (`firma_id`) REFERENCES `firmy` (`firma_id`) ON UPDATE CASCADE;


I przyznam, że się pogubiłem. Czy ktoś może mi pomóc/nakierować?
funkcja nad którą pracuję:
  1. function zlicz_wiadomosci_nieprzeczytane($uzytkownik_id) {
  2. global $connect;
  3.  
  4. $uzytkownik_id = (int)$uzytkownik_id;
  5.  
  6. $sql = "SELECT
  7. COUNT(konwersacje_wiadomosci.wiadomosc_ogladana) AS nieczytana
  8. FROM konwersacje_wiadomosci, konwersacje_czlonkowie
  9. WHERE konwersacje_wiadomosci.uzytkownik_id = {$_SESSION['uzytkownik_id']}
  10. AND konwersacje_wiadomosci.wiadomosc_ogladana = 0
  11. AND konwersacje_czlonkowie.konwersacja_ostatnio_ogladana = 0
  12. ";
  13.  
  14. $wynik = mysqli_query($connect, $sql);
  15.  
  16. if($wynik === FALSE) {
  17. die(mysqli_error($connect));
  18. } else {
  19. if($row = mysqli_fetch_row($wynik)) {
  20. return $row[0];
  21. }
  22. }
  23.  
  24. }
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
bostaf
post
Post #2





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


Hmm w takiej postaci nie ma możliwości ustalenia, kto jaką wiadomość przeczytał. Brakuje jednoznacznej informacji wskazującej, że dany użytkownik przeczytał daną wiadomość.

Masz "konwersacja_ostatnio_ogladana" w tabeli "konwersacje_czlonkowie", ale to tylko wskazuje kiedy dana konwersacja została otwarta w widoku do odczytu.

Masz "wiadomosc_ogladana" w "konwersacje_wiadomosci", ale to też nie wskazuje KTO oglądał daną wiadomość. Tylko tyle, że ktoś oglądał i już nie jest globalnie nieprzeczytana.

Jedyne co można z takimi danymi zrobić, to pokazać pierwszemu zalogowanemu uczestnikowi danej konwersacji, że ma N nieprzeczytanych wiadomości. W momencie jak ten użytkownik otworzy konwersację, to znaczniki się ustawią na 1 i kolejny użytkownik już będzie miał status "wszystko przeczytane".

Musiałbyś dodać jakąś tabelę, która powiąże id_wiadomosci, id_uzytkownika polem "przeczytana" (np.: "wiadomosci_przeczytane_przez"), i dopisywać tam rekordy w momencie otwarcia wiadomości do odczytu. Dodatkowo, autor wiadomości też tam powinien być dopisany w momencie wysyłania wiadomości.
Wtedy określenie ilości nieprzeczytanych wiadomości sprowadzałoby się do obliczenia różnicy a - b, gdzie:
a: ilość wszystkich wiadomości we wszystkich konwersacjach dla danego użytkownika
b: ilość wszystkich rekordów w tabeli "wiadomosci_przeczytane_przez" policzona dla id_wiadomosci z puli liczonej w "a"

To zadziała pod warunkiem, że rozumiesz że:
Cytat(gogomania @ 5.05.2017, 13:57:08 ) *
Np. 'admin' wysyła wiadomość do 'test_1' i 'test_2' [...] a w tabeli konwersacje_czlonkowie dodane zostaną 3 nowe wiersze z użytkownikami tej konwersacji oraz id konwersacji.

ta logika MOŻE spowodować pojawienie się duplikatów, i że programistycznie nie dopuszczasz do pojawienia się takich duplikatów.

Tak mi się wydaje.
Ale ogólnie na twoim miejscu mocno przemyślałbym ten model danych. Nie jestem pewien czy "konwersacja" jest tu w ogóle potrzebna, bo konwersację można ustalić dynamicznie na podstawie analizy łańcucha wiadomości:
1. Jedna wiadomość to logicznie już konwersacja. Bez odpowiedzi, ale konwersacja.
2. Dwie i więcej wiadomości to już porządna konwersacja, której początek, ciąg i koniec można ustalić dodając pole "w_odpowiedzi_na" przechowujące id_wiadomosci poprzedniej, ale jakiejkolwiek innej....
Go to the top of the page
+Quote Post
bostaf
post
Post #3





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


W takim razie zacytuję sedno tego, co napisałem w poprzednim poście:
Cytat(bostaf @ 5.05.2017, 15:11:35 ) *
Hmm w takiej postaci nie ma możliwości ustalenia, kto jaką wiadomość przeczytał. Brakuje jednoznacznej informacji wskazującej, że dany użytkownik przeczytał daną wiadomość.

Miałem tu na myśli, że w bazie danych nie masz w tej chwili informacji o tym kto jaką wiadomość przeczytał lub nie. Czyli nie skonstruujesz zapytania SQL które odpowie na Twoje pytanie.
Reszta tamtego posta to szybka analiza tego co masz dostępne i propozycja (jedna z kilku opcji) w jaki sposób taką funkcjonalność wdrożyć. Liczba nieprzeczytanych to przykład; taką samą techniką można te wiadomości pobrać.
Go to the top of the page
+Quote Post
gogomania
post
Post #4





Grupa: Zarejestrowani
Postów: 51
Pomógł: 1
Dołączył: 7.02.2013

Ostrzeżenie: (0%)
-----


Cytat(bostaf @ 6.05.2017, 13:58:08 ) *
W takim razie zacytuję sedno tego, co napisałem w poprzednim poście:

Miałem tu na myśli, że w bazie danych nie masz w tej chwili informacji o tym kto jaką wiadomość przeczytał lub nie. Czyli nie skonstruujesz zapytania SQL które odpowie na Twoje pytanie.
Reszta tamtego posta to szybka analiza tego co masz dostępne i propozycja (jedna z kilku opcji) w jaki sposób taką funkcjonalność wdrożyć. Liczba nieprzeczytanych to przykład; taką samą techniką można te wiadomości pobrać.


Przepraszam, może to nie niemożliwe, ale mam tą funkcjonalność tj. mam tą informację która wiadomość została przeczytana:
  1. function pobierz_sume_konwersacji() {
  2. global $connect;
  3. $sql = "SELECT
  4. k.konwersacja_id
  5. , k.konwersacja_temat
  6. , MAX(kw.data_wyslania) AS konwersacja_ostatnia_odpowiedz
  7. , MAX(kw.data_wyslania) > (kc.konwersacja_ostatnio_ogladana) AS konwersacja_nieprzeczytana
  8. FROM konwersacje AS k
  9. LEFT JOIN konwersacje_wiadomosci AS kw ON k.konwersacja_id = kw.konwersacja_id
  10. INNER JOIN konwersacje_czlonkowie AS kc ON k.konwersacja_id = kc.konwersacja_id
  11. WHERE kc.uzytkownik_id = {$_SESSION['uzytkownik_id']}
  12. AND kc.konwersacja_usunieta = 0
  13. GROUP BY k.konwersacja_id
  14. ORDER BY konwersacja_ostatnia_odpowiedz DESC
  15. ";
  16. $wynik = mysqli_query($connect, $sql);
  17. $konwersacje = array();
  18. while ($wiersz = $wynik->fetch_assoc()) {
  19. $konwersacje[] = array(
  20. 'id' => $wiersz['konwersacja_id'],
  21. 'temat' => $wiersz['konwersacja_temat'],
  22. 'ostatnia_odpowiedz' => $wiersz['konwersacja_ostatnia_odpowiedz'],
  23. 'wiadomosci_nieprzeczytane' => ($wiersz['konwersacja_nieprzeczytana'] == 1)
  24. );
  25. }
  26. return $konwersacje;
  27. }

W tej funkcji pobieram 'konwersacja_nieprzeczytana' i wyświetlam na liście konwersacji informację np. "Nowe" co jest jednoznaczne z tym, że są nowe wiadomości w konwersacji.

  1. function pobierz_wiadomosci_konwersacji($konwersacja_id) {
  2. global $connect;
  3. $konwersacja_id = (int)$konwersacja_id;
  4. $sql = "SELECT
  5. kw.data_wyslania
  6. , kw.data_wyslania > kc.konwersacja_ostatnio_ogladana AS konwersacja_nieprzeczytana
  7. , kw.wiadomosc_tresc
  8. , CONCAT(u1.imie,' ',u1.nazwisko) AS nadawca
  9. , u1.uzytkownik_id AS nadawca_id
  10. , u1.zdjecie
  11. FROM konwersacje_wiadomosci AS kw
  12. INNER JOIN konwersacje_czlonkowie AS kc ON kw.konwersacja_id = kc.konwersacja_id
  13. INNER JOIN uzytkownicy AS u1 ON u1.uzytkownik_id = kw.uzytkownik_id
  14. WHERE kw.konwersacja_id = {$konwersacja_id}
  15. AND kc.uzytkownik_id = {$_SESSION['uzytkownik_id']}
  16. ORDER BY kw.data_wyslania DESC";
  17. $wynik = mysqli_query($connect, $sql);
  18. $wiadomosci = array();
  19. while ($wiersz = $wynik->fetch_assoc()) {
  20. $wiadomosci[] = array(
  21. 'data' => $wiersz['data_wyslania'],
  22. 'nadawca' => $wiersz['nadawca'],
  23. 'nadawca_id' => $wiersz['nadawca_id'],
  24. 'zdjecie' => $wiersz['zdjecie'],
  25. 'nieprzeczytana' => $wiersz['konwersacja_nieprzeczytana'],
  26. 'tresc' => $wiersz['wiadomosc_tresc'],
  27. );
  28. }
  29. return $wiadomosci;
  30. }

Tutaj między innymi pobieram ile jest wiadomosci nieprzeczytanych dla danej konwersacji...

Ale brakuje mi jak wspomniałem funckji która wyświetli mi wszystkie nieprzeczytane wiadomości we wszystkich konwersacjach użytkownika. Tzn. zapytania SQL. Jakieś pomysły jak powinno składać wyglądać te zapytanie?
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 15.10.2025 - 15:16