Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Komentarze - drzewo cytatów
Forum PHP.pl > Forum > Przedszkole
mirobor
Jako początkujący w php, wyznaczam sobie coraz trudniejsze zadania praktyczne. Nadszedł czas, aby zwrócić, się do szanownego grona forum php w celu rozwiązania kolejnego wyzwania, które przed sobą postawiłem.

Część artykułów na swojej stronie publikuję z zewnętrznej bazy danych zaprzyjaźnionego portalu. Chciałbym publikować pod nimi również komentarze pobierane z tej samej bazy. Nie ma problemu z czystymi komentarzami, ale problem pojawia się, kiedy pojawia się w nich drzewo cytatów, czyli, kiedy komentujący cytuje innego komentującego, nie mówiąc już o większej ilości zagnieżdżeń.
W linku załączam screen poglądowy ze złożonym drzewem cytatów.
https://www.dropbox.com/s/5icnmwcllzwu4zq/komentarze.png

W tabeli bazy danych wygląda to tak jak poniżej. Sformatowałem zapis dla przejrzystości. W oryginale zamiast 'cite' jest 'quote', zamieniłem to, gdyż zdaje się to forum używa podobnego systemu i kod podlegał formatowaniu:

  1. Dolot emit rata tata i tak dalej tutaj komentarz nadrzędny
  2. [cite name="ania"]
  3. [cite name="user34"]
  4. [cite name="mieszkaniec"]
  5. [cite name="dwobor"]
  6. Lorem ipsum is that it has ...i tak dalej
  7. [/cite]
  8. Lorem ipsum is that ... i tak dalej
  9. [/cite]
  10. Normal distribution of... i tak dalej
  11. [/cite]
  12. Lorem ipsum.... i tak dalej
  13. [/cite]

Proszę o pomoc szanowne grono w celu wykonania tego zadania w sposób wydajny. Pewnie można by użyć bóg, wie ile funkcji explode, ale to przecież rozwiązanie tragicznie mało wydajne.
Jak rozumiem, najpierw muszę policzyć ilość cytatów, aby móc zdefiniować pętle 'for', następnie jak sądzę użyć wyrażeń regularnych, ale tu niestety moja wiedza już nie wystarcza.
Efektem pożądanym jest ten z załączonej grafiki w linku. Czyli wyłuskanie nazw użytkowników, ich komentarzy w celu zbudowania drzewa.

Oczywiście nie proszę o gotowe rozwiązanie. Proszę o sugestie i wszelkie pomysły, dzięki którym będę mógł doczytać co trzeba i wykonać to zadanie. Oczywiście będę wdzięczny za konkrety.
Z góry dziękuję.
Turson
Każdy cytat musi mieć swojego swoje parent_id, czyli id cytatu rodzica. Przy każdym wywołaniu cytatu sprawdzasz czy są jakieś cytaty które mają jego id jako id rodzica.
Lepiej pętlą foreach niż for, bo wtedy nie musisz znać ilości elementów.
mirobor
Dzięki, ale trochę to dla mnie za mało, na moim poziomie. Jak uzyskać/wytworzyć parent_id? Przykład odnoszący się do w/w danych z bazy bardzo by mi pomógł. O pętli foreach już czytam.

A przy okazji czytałem Twojego bloga i artykuł nt chatu ajaxowego. Próbowałem przetestować demo, ale chyba nie działa?
vonski
Ale po co tu pętla? Jeżeli chcesz tylko wyświetlić te komentarze z odpowiednimi zagłębieniami to wystarczy sam regexp i trochę CSS-a. Tzn. w CSS formatujesz odpowiednio <blockquote> tak żeby każdy następny miał zagłębienia (padding), a preg_replace zamieniasz wystąpienia [cite="..."] na <blockquote>Cytat: [nazwa usera]

Coś w tym rodzaju:

  1. $pattern = '/\[cite\sname="([a-z0-9]+)"\]/i';
  2. echo preg_replace(array($pattern, '#\[/cite\]#'), array("<blockquote><div>Cytat: \\1</div>", '</blockqoute>'), $html);


gdzie $html to zmienna z tekstem pobranym z bazy danych
mirobor
@vonski. CSS to małe miki, więc formatowaniem nie ma co się zajmować.
Tak myślałem, że użycie wyrażeń regularnych załatwi większość mojego problemu. Póki co to moja pięta achillesowa.
Dziękuję, przetestuję twój kod.
vonski
Wbrew pozorom nie są takie trudne.
Tutaj masz fajne źródła do nauki wyrażeń regularnych:

http://www.regular-expressions.info/tutorialcnt.html
http://uk1.php.net/manual/en/regexp.introduction.php

Wystarczy to raz zrozumieć i już się nie zapomni smile.gif
mirobor
@vonski
Działa prawie idealnie. Niestety w nickach userów występują nie tylko znaki alfanumeryczne. Czy póki nie doczytam szczegółów regexp mógłbyś mi pomóc zmodyfikować kod:
  1. $pattern = '/\[cite\sname="([a-z0-9]+)"\]/i';
vonski
Mógłbym, jakbym wiedział jakie znaki poza alfanumerycznymi mogą występować w nazwach nicków smile.gif
mirobor
Z dokumentacji wynika, że wszystkie oprócz:
  • nawiasów kwadratowych
  • apostrofów
  • cudzysłowów

czyli:
  • [
  • ]
  • '
  • "

vonski
W takim razie zamiast przedziału [a-z0-9] musisz tam wstawić wyrażenie pasujące do tych wymagań, czyli generalnie zaprzeczenie tych znaków. Zaprzeczenie robisz za pomocą: ^

  1. $pattern = '/\[cite\sname="([^\[\]\'"]+)"\]/i';
mirobor
@vonski
Działa perfekcyjnie. Obiecuję poczytać o regexp. Bardzo dziękuję za poświęcony czas i pomoc.



Zastosowałem i widzę jeszcze jeden przypadek, który muszę uwzględnić. Userzy próbują cytować, ale zdarza się, że podczas edycji usuwają rozpoczynający znacznik [cite name=..... ] lub kończący [/cite]. Efektem takiego działania jest dodatkowe niepotrzebne zagnieżdżenie w drzewie komentarzy.
Proszę o kopniaka w kierunku rozwiązania tego problemu.
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.