Webboard

Pełna wersja: Informacja o poście ukaranym ostrzeżeniem - hook'i
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Wersja skryptu MyBB: 1.6.9
Adres forum: nieistotne
Na czym polega problem (screen, opis, komunikaty, nazwa i wersja wtyczki):

Witam,
próbuję stworzyć na potrzeby własnego forum plugin, który pokazywał by użytkownikom, że dany post został ukarany ostrzeżeniem, wraz z jego powodem. Żeby zaoszczędzić zapytań do bazy, zrobiłem skrypt, który zbiera ID postów do tablicy $postID, w przeciwnym razie w ciągu jednego wejścia do tematu mogłoby się wykonywać zdecydowanie za dużo (jak dla mnie) zapytań, bo nawet do 10 przy domyślnych ustawieniach:
Kod PHP:
$plugins->add_hook("postbit""zbieranie_pid");
function 
zbieranie_pid($post){
    global 
$postID;
    if(!
count($postID)){
        
$postID = array();
    }
    
array_push($postID$post['pid']);
    return 
$post;

Rozumiem, że będę musiał dodać frazę, która następnie będzie zamieniana na ewentualną informację o ostrzeżeniu, jeśli dla danego posta istnieje.

Druga część kodu, w tej chwili wygląda tak:
Kod PHP:
$plugins->add_hook("showthread_end""wyszukiwanie_ostrzezen");
function 
wyszukiwanie_ostrzezen(){
    global 
$db$postID;
    if(
count($postID)){
        
$tidArray = array();
        
$query $db->query("SELECT A.`pid`, A.`tid`, A.`title`, B.`title` AS `title2` FROM `"TABLE_PREFIX ."warnings` AS A JOIN `"TABLE_PREFIX ."warningtypes` AS B WHERE A.`pid` IN ("implode(", "$postID) .") AND A.`tid` = B.`tid`;");
        while(
$row $db->fetch_array($query)){
            
//print_r($row);
        
}
    }

... jednak jak podejrzewam, wybrałem zły hook, gdyż nie da mi on możliwości na wykonanie podmienienia (chyba, że nie wiem o jakichś sztuczkach?). Szukałem tutaj: http://docs.mybb.com/MyBB_Plugin_Hooks.html odpowiedniego hook'a, lecz nie bardzo wiem, o który może chodzić.

Z góry dziękuję za jakąkolwiek okazaną mi pomoc. Jest to jak dotąd drugi mój plugin, jaki robię do MyBB, więc można powiedzieć, że jestem laikiem w tym silniku :)
:
Czytałeś post autora?
Plugin który podałeś robi to właśnie w sposób, którego autor chce uniknąć.


:
Niestety, ale trafiłeś na poważną ścianę... MyBB nie pozwala modyfikować zapytań, a jak zauważyłeś, nie ma jak "wrócić" do tamtego fragmentu po pobraniu danych z bazy. Sugeruję więc inne rozwiązanie - przy zbieraniu id dodaj od razu jakąś zmienną z kodem-komentarzem HTML np:

Kod PHP:
$post['warn_info'] = "<!-- POST_WARN_INFO_{$post['pid']}  -->"

(BTW. niepotrzebnie robisz return, argument powinien tam iść przez referencję)

No i potem w hooku przed wyrzuceniem strony na wyjście pobierasz dane i podmieniasz używając str_replace - masz pid'y, więc nie ma sensu zaprzegać regexa, to o wiele szybsza metoda.
Ja takiego rozwiązania używam w większości moich dodatków. Pozwala przebić się przez wspomniany problem.
Myślałem, że jest jakiś hook, który właśnie by "udostępniał" już wygenerowaną treść wątku. W tym wypadku posłużyłem się hook'iem: pre_output_page, który chociaż wykonuje się dla każdej ze stron, to i tak kończy się u mnie na warunku, który sprawdza, czy tablica $postID zawiera jakieś elementy.

Zamiast dodawania dodatkowego kodu-komentarza, użyłem już istniejącego:
Kod:
<div class="post_body" id="pid_XXX">
z użyciem str_replace (od razu zamierzałem jego użycie, tylko właśnie brakowało mi argumentu, który zawierałby wygenerowaną treść posta).

Udostępniam całość, gdyby ktoś potrzebował:
Kod PHP:
$plugins->add_hook("postbit""zbieranie_pid");
$plugins->add_hook("pre_output_page""wyszukiwanie_ostrzezen");

function 
zbieranie_pid(&$post)
{
    global 
$postID;
    if(!
count($postID))
    {
        
$postID = array();
    }
    
array_push($postID$post['pid']);
}

function 
wyszukiwanie_ostrzezen(&$page)
{
    global 
$db$postID;
    if(
count($postID))
    {
        
$query $db->query("SELECT A.`pid`, A.`tid`, A.`title`, B.`title` AS `title2`, A.`points` FROM `"TABLE_PREFIX ."warnings` AS A JOIN `"TABLE_PREFIX ."warningtypes` AS B WHERE A.`pid` IN ("implode(", "$postID) .") AND A.`tid` = B.`tid`;");
        while(
$row $db->fetch_array($query))
        {
            if(!empty(
$row['title2']))
            {
                
$reason $row['title2'];
            }
            else
            {
                
$reason $row['title'];
            }
            
$page str_replace("<div class=\"post_body\" id=\"pid_" $row['pid']. "\">""<div class=\"post_body\" id=\"pid_" $row['pid']. "\"><div class=\"post_warned\" style=\"border: 2px dotted red; background: #330000; font-weight: bold; color: red; padding: 2px;\"><br />* Autor postu otrzymał ostrzeżenie. Powód: " $reason " (+" $row['points'] . " " .(($row['points'] == 1)?("punkt"):((($row['points'] % 10 1)&&($row['points'] % 10 5)&&!(($row['points'] % 100 >= 10)&&($row['points'] % 100 <= 21)))?("punkty"):("punktów"))) . ").<br /><br /></div><br />"$page);
        }
    }


Temat wyczerpano, można zamknąć.