Skocz do zawartości
Pecetowicz Forum komputerowe

Jak napisać własną wtyczkę do MyBB. Kompleksowy poradnik.


Rekomendowane odpowiedzi

Witam. Przyszedł taki czas aby opisać proces pisania własnej wtyczki do MyBB. Postaram się to opisać w jak najprostszy sposób aby każdy zrozumiał.

Aby móc pisać plugin i jakoś go testować wypadałoby postawić sobie jakieś czyste forum na serwerze lub lokalnym komputerze z zainstalowanym np. XAMPPem. XAMPP to darmowe oprogramowanie pozwalające postawić sobie w szybki i prosty sposób serwer na domowym komputerze.

Jak już mamy działające forum to wchodzimy do folderu ./inc/plugins/ i w nim tworzymy plik *.php z nazwą naszego pluginu. W moim przypadku będzie to “mojplugin.php”.

Zabezpieczenia i informacje

Jedną z pierwszych rzeczy, które musimy zrobić to zabezpieczenie przed bezpośrednim wykonywaniem naszego skryptu przez użytkownika. W tym celu w naszym nowym pustym pliku wpisujemy następujący kod:

<?php
if(!defined("IN_MYBB")) die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
?>

Co robi powyższy kod? Otóż w każdym głównym pliku MyBB (np. index.php, showthread.php) zdefiniowana jest stała IN_MYBB. Każdy załączany później plik (np. plugin) ma dostęp do owej stałej. Ten kod sprawdza właśnie, czy stała IN_MYBB jest zdefiniowana w kodzie. Znak ! oznacza negację, tak więc jeśli IN_MYBB jest niezdefiniowane to interpreter zakończy wykonywanie skryptu z napisem “Direct initialization […]”.

Teraz musimy wpisać w plik podstawowe informacje o naszym pluginie oraz funkcje, które MyBB powinno wykonać w celu zainstalowania, odinstalowania, aktywowania lub dezaktywowania naszego pluginu. Służą do tego następujące funkcje:

  • nazwaPluginu_info() – wymagana
  • nazwaPluginu_install() – opcjonalna
  • nazwaPluginu_uninstall() – opcjonalna
  • nazwaPluginu_activate() – opcjonalna
  • nazwaPluginu_deactivate() – opcjonalna

MyBB rozpoznaje również funkcję nazwaPluginu_is_installed(), która sprawdza, czy nasz plugin jest zainstalowany (zwraca wartość logiczną np. prawdę, kiedy znajdzie w bazie danych tabelę, która została stworzona przez nasz plugin przy instalacji).

Oczywiście zamiast nazwaPluginu musimy wpisać nazwę naszego pliku *.php. W moim przypadku będzie to np. mojplugin_info()

Teraz musimy uzupełnić informacje o naszym pluginie. Funkcja nazwaPluginu_info() powinna zwracać tablicę asocjacyjną z następującymi kluczami:

  • name – nazwa pluginu,
  • description – opis pluginu,
  • website – strona www pluginu,
  • author – autor pluginu,
  • authorsite – strona www autora,
  • version – wersja pluginu,
  • guid – ang. Globally Unique Identifiers – Unikalny identyfikator pluginu, który owtrzymasz, jeśli wstawisz swoje dzieło na oficjalną stornę z modami do MyBB. Pozwala to użytkownikom sprawdzać, czy mają najnowszą wersję pluginu. Jeśli nie chcesz wysyłąć pluginu na mods.mybb.com, zostaw w tym polu pusty ciąg.
  • compatibility – kompatybilność naszego pluginu z odpowiednimi wersjami MyBB (np. jeśli wpiszemy tam “16*” to nasz plugin będzie kompatybilny z wszystkimi wersjami MyBB z numerkiem 1.6.x)

Po dopisaniu do naszego kodu funkcji odpowiedzialnej za przekazanie informacji o pluginie powinien on wyglądać tak:

<?php
if(!defined("IN_MYBB")) die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");

function mojplugin_info() {
	return array(
		"name"			=> "Mój plugin",
		"description"	=> "To jest mój pierwszy plugin do MyBB.",
		"website"		=> "http://krupson.eu/podstronamojegopluginu/",
		"author"		=> "Krupson",
		"authorsite"	=> "http://krupson.eu/",
		"version"		=> "1.0",
		"guid" 			=> "",
		"compatibility" => "1*"
	);
}
?>

Instalacja / deinstalacja pluginu

Niektóre pluginy mogą działać bez instalacji. Wystarczy je tylko aktywować z panelu admina i plugin już działa. Inne z kolei wymagają instalacji. Z czego to wynika? Załóżmy, że mamy plugin, który do każdego postu w MyBB dokleja na sztywno zdefiniowany ciąg oraz plugin realizujący funkcję czatu. Ten drugi musi wgrać do bazy danych swoje tabele, w których będzie przechowywał dane takie jak wpisy na czacie, lista zbanowanych użytkowników itp. Ten pierwszy zaś nie musi trzymać w bazie żadnych danych. Oddzielenie instalacji/deinstalacji od aktywacji/deaktywacji jest bardzo pomocne w sytuacji, kiedy chcemy np. na jakiś czas wyłączyć czat nie tracąc przez to wszystkich napisanych na nim do tej pory wpisów. Poniżej przedstawię przykładową realizację kodu do instalacji/deinstalacji pluginu.

function mojplugin_install() {
	global $db; // Normalnie z poziomu funkcji nie mamy dostępu do zmiennej $db, musimy uczynić ją widoczną wewnątrz funkcji, aby móc jej używać.
	
	// Teraz tworzymy naszą tabelę prostym zapytaniem SQL.
	$db -> write_query("CREATE TABLE `".TABLE_PREFIX."mojatabela` (
		`kolumna1` int(11) NOT NULL,
		`kolumna2` tinyint(1) NOT NULL,
		`kolumna3` int(11) NOT NULL
	) ENGINE=MyISAM");
}

function mojplugin_uninstall() {
	global $db;
	$db -> drop_table('mojatabela'); // Usuwamy naszą tabelę
}

function mojplugin_is_installed() {
	global $db;
	return $db -> table_exists('mojatabela'); // Sprawdzamy, czy nasza tabela istnieje. Jeśli tak - zwróci true, jeśli nie - zwróci false.
}

Nasz plugin potrafi się już przedstawić, zainstalować oraz odinstalować z poziomu ACP. Najwyższa pora, aby zaczął spełniać pewne funkcje. Niech napisany przez nas plugin zacznie pokazywać 10 najnowszych użytkowników na naszym forum.

Pierwsze co musimy zrobić to zdefiniować sobie funkcję, która pobierze z bazy 10 najnowszych użytkowników, sformatuje ich nicki, wygeneruje linki, sformatuje datę rejestracji, a następnie zapisze wynik swojej pracy do zmiennej $nowiUzytkownicy. Niech nasza funkcja nazywa się mojplugin_get_new_users().

Jednak skrypt forum wciąż nie wie co z nią zrobić. W MyBB istnieje coś takiego jak system haków (ang. hooks). Pozwala to podczepić samemu napisaną funkcję pod wybrany fragment kodu całego forum, w którym ma się ona wykonać. Pełną listę hooków można zobaczyć tutaj: Plugin Hooks

W kolumnie “Params” niektóre hooki mają podaną jakąś zmienną. Jest to zmienna, która jest przekazywana jako argument przez MyBB do naszej funkcji.

Ok, wiemy już co to są hooki, ale jak ich używać? Jest to bardzo proste. Wybieramy sobie w którym miejscu ma wykonywać się nasz kod (np. niech będzie na początku każdej strony w MyBB). W tym celu wybieramy sobie hooka o nazwie “global_start” i podpinamy pod niego naszą funkcję w następujący sposób:

$plugins -> add_hook('global_start', 'mojplugin_get_new_users');

Teraz, żeby nie przeciągać i niepotrzebnie się rozpisywać przedstawie kod funkcji realizującej te zadania z wyczerpującymi komentarzami 🙂

$plugins -> add_hook('global_start', 'mojplugin_get_new_users'); // Zaczepiamy naszą funkcję w global_start.

function mojplugin_get_new_users() {
	global $db, $nowiUzytkownicy; // Tak jak poprzednio zapewniamy sobie dostęp do potrzebnych nam zmiennych. Dodatkowo zmienna $nowiUzytkownicy jest defiuoniowana jako globalna, aby była ona dostępna poza naszą funkcją (w całym MyBB). Dzięki temu będziemy mogli wpisać w szablonie {$nowiUzytkownicy} w celu pokazania treści tej zmiennej w wybranym miejscu naszego forum.
	
	$q = $db -> simple_select('users', 'uid, username, usergroup, displaygroup, regdate', "", array(
		'order_by' => 'regdate',
		'order_dir' => 'DESC',
		'limit' => 10)
	); // Zapytanie do bazy danych o 10 najnowszych użytkowników. simple_select() przyjmuje parametry kolejno: tabela, nazwy kolumn, [warunki], [opcje np. sortowanie]
	
	$nowiUzytkownicy = "<h1>Najnowsi użytkownicy: </h1><ol>"; // Definiujemy naszą zmienną, w której umieścimy wynik dziłania naszego pluginu.
	
	
	while($r = $db -> fetch_array($q)) { // Sprawdzamy po jednym wyniku (tutaj: użytkowniku) na raz dopóki się nie skończą. Metoda fetch_array() dla danego zapytania zwraca po jednym wierszu z wyniku tego zapytania umieszczając dane w tablicy asocjacyjnej z kluczami o takich nazwach, jak nazwy kolumn.
		//$nowiUzytkownicy .= "<li>" .  . "</li>";
		$nowiUzytkownicy .= "<li>" . build_profile_link(format_name($r['username'], $r['usergroup'], $r['displaygroup']), $r['uid']); // W tym przypadku używamy 2 funkcji zdefiniowanych w MyBB - format_name($nazwa_uzytkownika, $grupa_uzytkownika, $wyswietlana_grupa) oraz build_profile_link($nazwa_uzytkownika, $id_uzywkownika, $target, $onclick)
		
		$nowiUzytkownicy .= " (" . date("d.m.Y H:i:s", $r['regdate']) . ")</li>"; // Dodajemy sformatowaną date rejestracji. Funkcja date() jest opisana w manualu PHP.
	}
	
	$nowiUzytkownicy .= "</ol>"; // Domykamy tag <ol>
}

Jak dodać ustawienia z poziomu ACP

Byłoby świetnie, gdyby w naszym pluginie dało się zmieniać ustawienia z poziomu ACP. Możemy oddać użytkownikowi możliwość zmiany np. liczby wyświetlanych najnowszych użytkowników z 10 na jakąś inną wartość. W tym celu musimy w funkcjach odpowiedzialnych za instalację, deinstalację oraz sprawdzenie, czy plugin jest zainstalowany umieścić następujący kod:

function mojplugin_install() {
	global $db; // Normalnie z poziomu funkcji nie mamy dostępu do zmiennej $db, musimy uczynić ją widoczną wewnątrz funkcji, aby móc jej używac.
	
	$db -> insert_query('settinggroups', array(
		"gid" => "NULL", // To pole jest 'auto increment', więc musimy podać tutaj NULL
		"name" => "mojplugin", // Nazwa
		"title" => "Ustawienia mojego pluginu", // Tytuł
		"description" => "Tu możesz zmieniać ustawienia mojego pluginu np. liczbę wyświetlanych najnowszych użytkowników.", // Opis
		"disporder" => "1", // Kolejność wyświetlania
		"isdefault" => "1"
	)); // Dodajemy do bazy grupę ustawień dla naszego pluginu.
	
    $id = $db -> insert_id(); // Zapisujemy do zmiennej $id identyfikator naszej grupy.
	
	$db -> insert_query('settings', array( // Dodajemy do bazy poszczególne ustawienia.
		"sid" => "NULL", // To pole jest 'auto increment', więc musimy podać tutaj NULL
		"name" => "mojplugin_liczba_uzytkownikow", // Unikalny identyfikator ustawienia
		"title" => "Liczba wyśw. użytkowników", // Tytuł
		"description" => "Liczba najnowszych użytkowników wyświetlanych przez plugin (zalecane 10).", // Opis
		"optionscode" => "text", // Typ pola
		"value" => "10", // Wartość
		"disporder" => "1", // Kolejnośc wyświetlania
		"gid" => $id, // ID grupy ustawień
		"isdefault" => "1"
	));

    rebuild_settings(); // Teraz musimy odświeżyć ustawienia.
}

function mojplugin_uninstall() {
	global $db;
	
	$id = $db -> simple_select('settinggroups', 'gid', "name = 'mojplugin'");
	$id = $db -> fetch_field($id, 'gid'); // Pobieramy identyfikator grupy ustawień
	$db -> delete_query('settinggroups', "name = 'mojplugin'"); // Usuwamy grupę ustawień
	$db -> delete_query('settings', "gid = {$id}"); // Usuwamy ustawienia z naszej grupy
}

function mojplugin_is_installed() {
	global $db;
	$q = $db -> simple_select('settinggroups', '*', "name = 'mojplugin'");
	if($db -> num_rows($q)) return true;
	else return false;
}

Następnie musimy odrobinę przerobić kod naszej głównej funkcji. Po pierwsze musimy dodać do zmiennych globalnych funkcji zmienną $mybb:

global $db, $mybb, $nowiUzytkownicy;

Po drugie zamieniamy linijkę, w której określamy ilość wyników zwracanych z bazy na:

'limit' => (int) $mybb -> settings['mojplugin_liczba_uzytkownikow'])

Właśnie dlatego musieliśmy dodać $mybb do zmiennych globalnych. Obiekt ten zawiera w sobie tablicę ‘settings’, w której znajdują się wszystkie ustawienia.

Finalny kod naszego pluginu

Po tym wszystkim cały kod naszego pluginu powinien wyglądać tak:

<?php
if(!defined("IN_MYBB")) die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");

function mojplugin_info() {
	return array(
		"name"			=> "Mój plugin",
		"description"	=> "To jest mój pierwszy plugin do MyBB.",
		"website"		=> "http://mojastrona.pl/podstronamojegopluginu/",
		"author"		=> "Krupson",
		"authorsite"	=> "http://mojastrona.pl/",
		"version"		=> "1.0",
		"guid" 			=> "",
		"compatibility" => "1*"
	);
}

function mojplugin_install() {
	global $db; // Normalnie z poziomu funkcji nie mamy dostępu do zmiennej $db, musimy uczynić ją widoczną wewnątrz funkcji, aby móc jej używac.
	
	$db -> insert_query('settinggroups', array(
		"gid" => "NULL", // To pole jest 'auto increment', więc musimy podać tutaj NULL
		"name" => "mojplugin", // Nazwa
		"title" => "Ustawienia mojego pluginu", // Tytuł
		"description" => "Tu możesz zmieniać ustawienia mojego pluginu np. liczbę wyświetlanych najnowszych użytkowników.", // Opis
		"disporder" => "1", // Kolejność wyświetlania
		"isdefault" => "1"
	)); // Dodajemy do bazy grupę ustawień dla naszego pluginu.
	
    $id = $db -> insert_id(); // Zapisujemy do zmiennej $id identyfikator naszej grupy.
	
	$db -> insert_query('settings', array( // Dodajemy do bazy poszczególne ustawienia.
		"sid" => "NULL", // To pole jest 'auto increment', więc musimy podać tutaj NULL
		"name" => "mojplugin_liczba_uzytkownikow", // Unikalny identyfikator ustawienia
		"title" => "Liczba wyśw. użytkowników", // Tytuł
		"description" => "Liczba najnowszych użytkowników wyświetlanych przez plugin (zalecane 10).", // Opis
		"optionscode" => "text", // Typ pola
		"value" => "10", // Wartość
		"disporder" => "1", // Kolejnośc wyświetlania
		"gid" => $id, // ID grupy ustawień
		"isdefault" => "1"
	));

    rebuild_settings(); // Teraz musimy odświeżyć ustawienia.
}

function mojplugin_uninstall() {
	global $db;
	
	$id = $db -> simple_select('settinggroups', 'gid', "name = 'mojplugin'");
	$id = $db -> fetch_field($id, 'gid'); // Pobieramy identyfikator grupy ustawień
	$db -> delete_query('settinggroups', "name = 'mojplugin'"); // Usuwamy grupę ustawień
	$db -> delete_query('settings', "gid = {$id}"); // Usuwamy ustawienia z naszej grupy
}

function mojplugin_is_installed() {
	global $db;
	$q = $db -> simple_select('settinggroups', '*', "name = 'mojplugin'");
	if($db -> num_rows($q)) return true;
	else return false;
}

$plugins -> add_hook('global_start', 'mojplugin_get_new_users'); // Zaczepiamy naszą funkcję w global_start.

function mojplugin_get_new_users() {
	global $db, $mybb, $nowiUzytkownicy; // Tak jak poprzednio zapewniamy sobie dostęp do potrzebnych nam zmiennych. Dodatkowo zmienna $nowiUzytkownicy jest defiuoniowana jako globalna, aby była ona dostępna poza naszą funkcją (w całym MyBB). Dzięki temu będziemy mogli wpisać w szablonie {$nowiUzytkownicy} w celu pokazania treści tej zmiennej w wybranym miejscu naszego forum.
	
	$q = $db -> simple_select('users', 'uid, username, usergroup, displaygroup, regdate', "", array(
		'order_by' => 'regdate',
		'order_dir' => 'DESC',
		'limit' => (int) $mybb -> settings['mojplugin_liczba_uzytkownikow'])
	); // Zapytanie do bazy danych o 10 najnowszych użytkowników. simple_select() przyjmuje parametry kolejno: tabela, nazwy kolumn, [warunki], [opcje np. sortowanie]
	
	$nowiUzytkownicy = "<h1>Najnowsi użytkownicy: </h1><ol>"; // Definiujemy naszą zmienną, w której umieścimy wynik dziłania naszego pluginu.
	
	
	while($r = $db -> fetch_array($q)) { // Sprawdzamy po jednym wyniku (tutaj: użytkowniku) na raz dopóki się nie skończą. Metoda fetch_array() dla danego zapytania zwraca po jednym wierszu z wyniku tego zapytania umieszczając dane w tablicy asocjacyjnej z kluczami o takich nazwach, jak nazwy kolumn.
		//$nowiUzytkownicy .= "<li>" .  . "</li>";
		$nowiUzytkownicy .= "<li>" . build_profile_link(format_name($r['username'], $r['usergroup'], $r['displaygroup']), $r['uid']); // W tym przypadku używamy 2 funkcji zdefiniowanych w MyBB - format_name($nazwa_uzytkownika, $grupa_uzytkownika, $wyswietlana_grupa) oraz build_profile_link($nazwa_uzytkownika, $id_uzywkownika, $target, $onclick)
		
		$nowiUzytkownicy .= " (" . date("d.m.Y H:i:s", $r['regdate']) . ")</li>"; // Dodajemy sformatowaną date rejestracji. Funkcja date() jest opisana w manualu PHP.
	}
	
	$nowiUzytkownicy .= "</ol>"; // Domykamy tag <ol>
}
?>
Odnośnik do odpowiedzi
Udostępnij na innych stronach

Problem wciąż nierozwiązany? Dodaj swoją odpowiedź

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto. Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...