Z góry uprzedzam, że poradnik nie jest w języku łopatologicznym. Osoby nie znające PHP (strukturalnie i choć trochę obiektowo) przed przeczytaniem poradnika zapraszam do księgarni po jakąś książke celem edukacji wstępnej ;)

Pluginy w MyBB potrafią rządzić danymi latającymi na drodze forum-użytkownik w tę i z powrotem za pomocą hooków. Hook (ang. hak) jak sama nazwa wskazuje pozwala nam "zahaczyć" się w jakimś miejscu forum, zrobić małe fiki-miki biegającym wokół tego miejsca danym, i wypuścić je w dalszą drogę.

Pluginem jest plik *.php o odpowiedniej strukturze. Postaram się ją nieco omówić.

1. Nazwa - nazwa pliku z pluginem nie może być przypadkowa. Swojemu pluginowi musimy wymyślić nazwę "surową", a więc bez kalafiorów w postaci spacji, kropek itp.; spełniającą kryteria nazywania funkcji w PHP - na przykład "uczesie". Taki plugin zapiszemy w pliku "uczesie.php". Nazwą "uczesie" będziemy też zaczynać wszystkie funkcje plugina. Oczywiście, dystrybuować plugin możemy pod nazwą bardziej marketingowo poprawną, np. "Uczę się 1.1 XP Beta" ;)

2. Bezpieczeństwo - pierwsze, co plugin powinien robić, to sprawdzić, czy nie został brutalnie wyciągnięty za fraki z reszty mechanizmu. Sprawdzamy więc, czy stała, która jest definiowana gdzieś w plikach jądra forum, jest zdefiniowana - niech to będą pierwsze linijki plugina.
if(!defined("IN_MYBB"))
{
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
}

3. Kto ja jestem - plugin musi umieć się przedstawić użytkownikowi w Panelu Admina. Będzie to robił za pomocą funkcji nazwaplugina_info(). Funkcja zawsze ma zwracać tablicę asocjacyjną o takiej samej strukturze:

function uczesie_info()
{
return array(
"name" => "Uczę się",
"description" => "Miejsce na opis plugina. Ja się uczę, więc wiele pisał nie będę.
Ale warto wiedzieć, że <b>można tu używać HTMLa</b>!",
"website" => "http://adres.strony.plugna.com/moze-pozostac-pusty",
"author" => "twój nick",
"authorsite" => "http://adres.twojej.strony.domowej.com/moze-pozostac-pusty",
"version" => "wersja 1.2",
);
}

4. Aktywacja i deaktywacja - nasz plik musi też zawierać funkcje, które będą wywoływane w momencie aktywacji i deaktywacji. Przydaje się to, jeśli plugin tworzy sobie jakieś dodatkowe tabelki albo kolumny w bazie danych - dzięki temu sam może sobie uwić gniazdko, a później po sobie posprzątać. Póki co - niech te funkcje u nas będą puste.

function uczesie_activate()
{

}

function uczesie_deactivate()
{

}

5. Hooki
Przechodzimy do sedna sprawy. W tym momencie musimy już wiedzieć, co nasz plugin ma robić. W przykładzie zajmiemy się najpierw doklejaniem jakiejś frazy do kazdego wysyłanego posta, a później zmodyfikujemy kod i będziemy ją doklejać do co drugiego posta użytkownika.

Skoro mamy wprowadzać zmiany w wysyłanym poście, odszukajmy hook, którym zahaczymy się w miejscu, gdzie nowy post jest dodawany do bazy. W tym celu przyda się troszkę intuicji i umiejętności czytania cudzego kodu.

Wszystko, co jest dodawane do bazy w MyBB, jest najpierw filtrowane przez klasę DataHandler i jej rozszerzenia. Postami zajmuje się klasa
class PostDataHandler extends DataHandler
umieszczona w pliku inc/datahandlers/post.php. Otwórzmy go.

Używając wbudowanej w swój edytor kodu wyszukiwarki, znajdźmy miejsca, w których są jakieś miejsca na hooki. Po prostu wyszukajmy wywołania metod run_hooks i run_hooks_by_ref. W okolicach 654 linijki znajdziemy ciąg znaków
$plugins->run_hooks_by_ref("datahandler_post_insert_post", $this);
Po nazwie hooka (datahandler_post_insert_post) możemy wywnioskować, że jest on wywoływany w momencie dodawania posta do bazy. To chyba to, czego szukaliśmy!

W tym momencie warto wspomnieć o dwóch sposobach wywoływania hooków. Jeden, to run_hooks() - uruchamia funkcje pluginów tutaj zaczepionych bez przekazywania im żadnych argumentów. Drugi to run_hooks_by_ref(), przekazujący wybraną zmienną jako argument do funkcji obsługującej hooka. W naszym przykładzie przekazywane jest $this, czyli obiekt klasy PostDataHandler.

Dodajemy hooka do naszego pluginu. Po pierwsze, tworzymy funkcję nazwaplugina_nazwa_hooka(), pamiętając o tym, że dostajemy coś w argumencie.
function uczesie_datahandler_post_insert_post($it)
{

}
Następnie rejestrujemy hook. Odbywa się to przez wywołanie metody add_hook(string nazwaHooka, string nazwaFunkcjiKtoraGoObsluguje) z obiektu $plugins. Dodajemy więc linijkę
$plugins->add_hook("datahandler_post_insert_post", "uczesie_datahandler_post_insert_post");
gdzieś w ciągu pliku (nie w żadnej z funkcji, oczywiście). Dla porządku - umieśćmy ją nad deklaracją funkcji uczesie_info().

Mając przekazany obiekt klasy PostDataHandler, możemy z nim zrobić co się nam żywnie podoba, na przykład dopisać coś do niesionej przezeń wiadomości; ta jest przechowywana pod indeksem 'message' tablicy asocjacyjnej post_insert_data będącej polem klasy, jaką stanowi przekazany w argumencie obiekt:
function uczesie_datahandler_post_insert_post($it)
{
$it->post_insert_data['message'] .= "\nA ja się [b]uczę[/b]!";
}

Jak widać, możemy tu stosować MyCode - wiadomości są z niego parsowane w momencie wyświetlania, a nie zapisu. Funkcja przetwarzająca hook nie musi nic zwracać.

W czasie tworzenia pluginów warto posługiwać się funkcjami PHP takimi jak var_dump() czy print_r() w celu wyśledzenia sposobu zapisu danych i otwarcia sobie drogi do manipulacji nimi.

Warto pamiętać, że hook datahandler_post_insert_post jest wywoływany tylko w momencie odpowiedzi na temat; gdy wysyłany post jest pierwszym w temacie, wywołuje się datahandler_post_insert_thread_post.



Nie jesteśmy jednak ograniczeni do operowania na przekazywanych nam argumentach. Możemy bowiem wyciągnąć dla siebie zmienne, które w okolicy naszego hooka biegają, za pomocą słówka global. Mamy też możliwość wykorzystywania funkcji wbudowanych w MyBB. Dzięki temu możemy na przykład uzależnić to, czy dopiszemy coś do posta, czy nie, od liczby postów użytkownika. W tym celu zglobalizujemy sobie zmienną $post zaobserwowaną gdzieś przy 643 linijce pliku inc/datahandlers/post.php
"uid" => $post['uid'],
Pobierzemy z niej ID piszącego (co prawda moglibyśmy je pobrać z przekazanego nam argumentu, ale dla edukacji udajmy, że o tym nie wiemy), a następnie na podstawie ID zapoznamy się z informacjami na temat użytkownika.

function uczesie_datahandler_post_insert_post($it)
{
global $post; // globalizacja zmiennej
$user = get_user($post['uid']); // get_user(int IdUzykownika) to funkcja wbudowana w jadro MyBB
if ($user['postnum']%2) $it->post_insert_data['message'] .= "\nA ja się [b]uczę[/b], w co drugim poście!"; // jesli liczba postow parzysta, to dopisujemy cos do wiadomosci
}


Na koniec przypomnę, że pliki z polskimi ogonkami w MyBB należy zapisywać w kodowaniu UTF-8 bez BOM, co umożliwia na przykład edytor Notepad++.

W załączniku plik uczesie.php, który powstał w poradniku ;)


Załączone pliki
.php   uczesie.php (Rozmiar: 1,13 KB / Pobrań: 136)