Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: algorytm, rozwiazanie, komunikacja użytkowników, poczta
Forum PHP.pl > Inne > Hydepark
AxZx
witam

chciałbym poznać Wasz sposób na system komunikacji użytkowników w serwisach społecznościowych.

co jest potrzebne:
- wysyłanie, odbieranie poczty
- możliwość usuwania poczty, przenoszenia do kosza
- możliwość przeglądania poczty odebranej, wysłanej i tej w koszu

w zasadzie to tyle 'kłopotliwych' kwestii.
ja zrobiłem tabele poczta i pogubiłem się podczas programowania. czy nie prościej byłoby zrobić 2 tabele: odebrane i wysłane?

podzielcie się swoimi rozwiązaniami.

pozdrawiam
kwiateusz
a nie prosciej dac pole okreslajace czy wiadomosc jest w inbox, sent czy trash?
AxZx
no prosciej, ale prosze o bardziej wyczerpujaca odpowiedz:)
mam kolumne kosz, mam kolumne przeczytane.
ale przeciez u nadawcy moze byc ona w koszu a u odbiorcy juz nie koniecznie:)
a to przeciez ten sam wiersz jest.
wiec musza byc 2 kolumny z typem wiadomosci - tzn z miejscem skladowania.
ale musi tez byc mozliwosc calkowitego usuniecia - nawet z kosza.
jak odbiorca usunie ta wiadomosc na stale to u nadawcy nie koniecznie musi byc ona usunieta:)

wiec dlatego pomyslalem o dwoch tabelach - tak jak jest w normalnej poczcie.
odbiorca i nadawca ma ja na serwerze, lub sobie ja usuwa nie wplywajac na konto pocztowe drugiej strony.
tiraeth
Kod
id | sender | receiver | ... | status
---+--------+----------+-----+----------
1  |    321 |      123 | ... | unreaded
2  |    321 |      123 | ... | deleted
3  |    321 |      123 | ... | readed
4  |    123 |      321 | ... | readed


Inbox for "123":
  - ID:1, STATUS:unreaded
  - ID:3, STATUS:readed
  
Trash for "123":
  - ID:2, STATUS:deleted

Sent for "123":
  - ID:4, STATUS:received, RESPONSE_TO:3

Inbox for "321":
  - ID:4, STATUS:readed, RESPONSE_TO:3
  
Sent for "321":
  - ID:1, STATUS:received and unreaded
  - ID:2, STATUS:received
  - ID:3, STATUS:readed and responded (ID:4)


Ja bym zrobił to tak smile.gif
AxZx
troche nie rozumiem tego twojego zapisu.
dodam ze pisze aplikacje na symfony - pierwszy raz mam do czynienia z tym FW i dla mnie to jest bardzo zamieszane.

bo zalozmy sytuacje ze jest 1 tabela no i kolumny z ID odbiorcy nadawcy, jakies flagi czy przeczytane, w ktorym folderze u kogo sie znajduje (folder_odbiorcy, folder_nadawcy) no i user przeglada tylko te z kosza. w koszu sa chyba listy odebrane i wyslane. wiec trzeba zrobic joina do profilu nadawcy i do profilu odbiorcy.

takze to tez jest warunek - zeby mozna bylo prosto napisac aplikacje w symfony:)
tiraeth
Moje rozwiązanie może Ci nie pasować - owszem. Wyjaśnię tylko, dlaczego możliwość usuwania wysłania wiadomości jest rzeczą zbędną. Ja uważam, że to użytkownik otrzymujący wiadomość powinien mieć pełne uprawnienia. Gdy "usunie do Trash" wiadomość, jej status zmieni się na deleted. Gdy usunie ją z Trasha, zmieni się na hidden. Fizycznie wiadomości nie usuwamy, bo musi pozostać ona w "Sent" naszego użytkownika-nadawcy.

Widzę, że próbujesz na siłę zaimplementować funkcjonalność SMTP/IMAP w prostą (z założenia potrzeb) aplikację prywatnych wiadomości. Jeśli o to Ci chodzi, to może z automatu zakładaj skrzynki mailowe z virtuaboxami na sql, stwórz webmaila i ogranicz możliwość wysyłania i odbierania wiadomości do adresatów z Twojej domeny. I voila smile.gif Będzie to o tyle lepsze rozwiązanie niż tradycyjne PW, że delikwent będzie mógł pobrać wiadomości (zostawiając kopię - ustawienia serwera, nie klienta) na komputer korzystając z np. Outlooka i przeglądać je nawet gdy serwis będzie offline. Oczywiście prosto z Outlooka będzie mógł odpisać lub napisać nową wiadomość smile.gif Czyli taki "intramail" globalnie winksmiley.jpg
AxZx
ale czy konieczne jest trzymanie zbednych wiadomosci? jak obydwie strony ja usuna to po co mi ona ma miejsce w bazie zajmowac?
ale czy dobrze rozumuje z tymi dwoma kolumnami?
bo jak nadawca zmieni status deleted to nie koniecznie musi oznaczac ze odbiorca tez ma ja miec w koszu.
wiec chyba to jest jedyna droga?


Cytat
Widzę, że próbujesz na siłę zaimplementować funkcjonalność SMTP/IMAP

tez o takim czyms myslalem. ale z drugiej strony informacja na maila o nowej poczcie jest motywacja zeby wejsc na strone i przy okazji cos tam poogladac, kliknac reklame:)

takze to bym zrobil w ramach pracy dyplomowej ale juz magisterskiej:) jak zdaze oczywiscie.
Moli
Akurat teraz pisałem prywatne wiadomości i ja zrobiłem to na jednej tabeli. Tabela wygląda w skrócie tak:
Kod
ID | OD_ID | DO_ID | KATALOG | TYTUŁ ITP...

I w katalogu wysłane, sprawdzam po prostu nie od kogo jest wiadomość a do kogo smile.gif Tak naprawdę cały mechanizm to pobranie danych, przenoszenie i kasowanie wiadomości + kilka ifów żeby w folderze wysłane nie wyświetlało się "Od" tylko "Do" smile.gif
AxZx
daj linka do testow:) bo cos za latwo to opisujesz.
.radex
A nie można po prostu

id | sender | receiver | ... | status_sender | status_receiver

To jest chyba najprostsze rozwiązanie. Wysyłający i otrzymujący mają osobną kolumnę na status (kolumny typu ENUM). I tyle.
Sedziwoj
Cytat(AxZx @ 1.08.2008, 01:40:16 ) *
ale czy konieczne jest trzymanie zbędnych wiadomości? jak obydwie strony ja usuną, to po co mi ona ma miejsce w bazie zajmować?


Takie rzeczy lepiej przechowywać, bo mogą się potem przydać w razie jakiś kłopotów.
Ludzie wysyłają dziwne wiadomości i lepiej je zawsze mieć.

EDIT: zresztą jak się nie mylę to tak robią większe portale społecznościowe, a na pewno mają jakiś cel w tym.
athabus
Zrób tak jak radex_p radzi - to jest imho najlepsze rozwiązanie. Dodatkowo weź pod uwagę co pisze Sedziwoj bo faktycznie, lepiej przez jakiś czas przechowywać takie wiadomości "na zapas", nawet jeśli odbiorca i nadawca tą wiadomość usuną.
Według mnie tu zastosowanie znajdzie cron - poprostu napisz prosty skrytp, który raz dziennie uruchomisz z crona, który usunie wszystkie wiadomości oznaczone przez obu userów jako "usunięte" i starsze niż x dni.
AxZx
to rozwiazanie tez wydaje mi sie najrozsadniejsze -w teorii:)
ale teraz to trzeba napisac w symfony:P
dlatego pisalem o czyms bardziej przejrzystym tak zeby jasniej to bylo napisane (kod).
legorek
Cytat(radex_p @ 1.08.2008, 08:03:02 ) *
A nie można po prostu

id | sender | receiver | ... | status_sender | status_receiver

To jest chyba najprostsze rozwiązanie. Wysyłający i otrzymujący mają osobną kolumnę na status (kolumny typu ENUM). I tyle.


Pole powinno być raczej typu SET, ponieważ wiadomość określona jest dwoma parametrami
położenie: otrzymane, wysłane, kosz
status: przeczytana, nieprzeczytana
z których można stworzyć różne kombinacje:
np: mogę przenieść nieprzeczytaną wiadomość do kosza, ale chciałbym zachować informację, że jest nieprzeczytana smile.gif
AxZx
jaki typ kolumn to juz mniej istotna kwestia.

ustalilismy juz jak ma wygladac tabela
podsumowujac:
  1. CREATE TABLE `poczta` (
  2. `idpoczta` int(11) NOT NULL AUTO_INCREMENT,
  3. `temat` varchar(60) DEFAULT NULL,
  4. `tresc` text,
  5. `idprofil_nadawca` int(11) NOT NULL,
  6. `idprofil_odbiorca` int(11) NOT NULL,
  7. `przeczytane` tinyint(2) UNSIGNED DEFAULT '0',
  8. `status_nadawca` tinyint(2) UNSIGNED DEFAULT '0',
  9. `status_odbiorca` tinyint(2) UNSIGNED DEFAULT '0',
  10. `created_at` datetime DEFAULT NULL,
  11. `updated_at` datetime DEFAULT NULL,
  12. PRIMARY KEY (`idpoczta`),
  13. KEY `poczta_FI_1` (`idprofil_nadawca`),
  14. KEY `poczta_FI_2` (`idprofil_odbiorca`)
  15. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;


kolumny status_nadawca i status_odbiorca moga przyjmowac wartosci:
0 - normalna wiadomosc
1 - wiadomosc w koszu
2 - wiadomosc usunieta

kazda akcja usuniecia zwieksza wartosc w kolumnie status_odbiorca lub status_nadawca.
czyli jak user chce przeniesc wiadomosc z folderu odebrane to zmienia sie na 1. jak chce usunac w kosza to zmienia sie na 2 i juz jej nie zobaczy nigdzie.

teraz juz pytanie techniczne
jak powinno wygladac zapytanie pobierajace dane dla akcji pokazKosz.
chcialbym tam polaczyc dane o profilach (nadawca, odbiorca).
zalozmy ze jestem zalogowany na idprofil = 2.
to bedzie cos takiego?

  1. SELECT * FROM poczta WHERE (idprofil_odbiorca = 2 AND status_odbiorca = 1) OR (idprofil_nadawca = 2 AND status_nadawca = 1)
Sedziwoj
@AxZx
Moim zdaniem pole status powinno być FK do tabeli z statusami.
.radex
dlaczego tinyint(2) a nie tinyint(1) ?
Sedziwoj
Cytat(radex_p @ 1.08.2008, 16:19:23 ) *
dlaczego tinyint(2) a nie tinyint(1) ?


A co to za różnica? Przecież to i tak nie ma nic wspólnego z długością pola.
Cytat
Another extension is supported by MySQL for optionally specifying the display width of integer data types in parentheses following the base keyword for the type (for example, INT(4))
.radex
Cytat(Sedziwoj @ 1.08.2008, 17:41:37 ) *
A co to za różnica? Przecież to i tak nie ma nic wspólnego z długością pola.


Masz rację. Zapomniałem o tym. Zwracam honor tongue.gif
superfrajer
Ja bym zrobil tak:

Message:
MessageId
Title
Description
CreatedAt
ReadAt

MessageStatus:
MessageStatusId
MessageId
UserId
DirectoryId


Wyslanie wiadomosci:
1) Tworzysz rekord Message, wypelniasz odpowiednie pola, ReadAt moze byc np. null
2) Tworzysz dwa rekordy MessageStatus:
Dla wysylajacego:
jego UserId, DirectoryId na rekord slownika Directories z 'Sent'
Dla odbierajacego:
UserId - id odbiorcy, DirectoryId - 'Inbox'

Gdy odbiorca otworzy wiadomosc (i wiadomosc nie jest w DirectoryId - 'Sent'):
1) Odswiezasz rekord z MessageId wpisujac do pola ReadAt aktualna date

Usuniecie wiadomosci:
1) Sprawdzasz czy dla kazdego MessageStatus z tym samym MessageId DirectoryId wskazuje na 'Deleted' (nie 'Trash', tam sobie wiadomosci moga lezec)

Dzieki temu rozwiazaniu uzytkownicy maja niezalezna kontrole nad wiadomoscia. Rowniez mozna wysylac wiadomosci
do wielu uzytkownikow na raz, oszczedzajac miejsce w bazie danych.
Tabela MessageStatus nie musi zawierac MessageStatusId, poniewaz mozna uznac ze MessageId + UserId bedzie zawsze unikalne.
Ale to kwestia gustu.

edit:
Dla wygody mozesz potem sobie stworzyc widok w postaci

Message + MessageStatus zlaczony po MessageId

edit:
Oczywiscie nie bedzie informacji o nadawcy i odbiorcy, ale to kwestia komplikacji widoku troche smile.gif Ale to niech ktos sie pomeczy bo ja spadam do domu smile.gif
Sedziwoj
@superfrajer
To rozwiązanie ma jedną wadę, wymaga złączenia tabel, do tego wiadomość w serwisach społecznościowych jest wysyłana do jednej osoby, więc dwie kolumny ze statusami wcale nie są gorszym rozwiązaniem, a wydajniejszym.
AxZx
nie bardzo rozumiem po co osobna tabela ze statusami. co tam ma byc przechowywane? mi sie wydaje ze w kolumnie status_odbiorca beda wartosci 0 - normalna wiadomosc, 1 - wiadomosc w koszu, 2 - wiadomosc usunieta. to tyle:)
tiraeth
1. Dwie tabele nie są potrzebne.
2. Zarówno status_odbiorca i status_nadawca powinny być polem SET z opcjami:
{normalna, nieprzeczytana}, {normalna, przeczytana}, {kosz, nieprzeczytana}, {kosz, przeczytana}, {usunieta, nieprzeczytana}, {usunieta, przeczytana}

smile.gif I problem rozwiązany smile.gif
AxZx
ten ostatni przyklad komplikuje uzycie z wykorzystaniem symfony:)
dzieki temu ze bedzie osobna kolumna przeczytane moge w symfony wykonac prosty warunek
  1. <?php
  2. $c->add(PocztaPeer::STATUS, true);
  3. ?>


i po sprawie:)

dzieki wszystkim za odpowiedzi, chyba juz nie ma wiecej pomyslow?smile.gif
nrm
@AxZx: i wróciłeś do punktu wyjścia tongue.gif a za odpowiedzi na priv nie dajesz pomógł? biggrin.gif
AxZx
Cytat
@AxZx: i wróciłeś do punktu wyjścia tongue.gif


hmm nie koniecznie.
zrobilem to w symfony - nie bylo tak strasznie. wiec to rozwiazanie jest dosyc dobre.
jeszcze tylko problem z polaceniem tabeli profil w folderze kosz - tam trzeba 2 razy laczyc tabele profil.

Cytat
a za odpowiedzi na priv nie dajesz pomógł? biggrin.gif

tym razem daje:)
kwiateusz
Dosyc mialo być na PW, tyle zniosłem ale wystarczy. Jeszcze jedna sporna wypowiedź a dam wam po warnie jak nie moderacji postów...

Zbedne posty usunalem, jeszcze mnie tak przed urlopem denerwowac
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.