Tworzenie wtyczek (dodatków) do $Projectname ============================================ Przypuszczalnie chcesz, aby $Projectname zrobił coś, czego jeszcze nie robi. Jest wiele sposobów. Ale nauczmy się, jak napisać wtyczkę lub dodatek. W katalogu $Projectname prawdopodobnie zobaczysz podkatalog o nazwie "addon". Jeśli jeszcze go nie masz, utwórz go. mkdir addon Następnie wymyśl nazwę swojego dodatku. Prawdopodobnie masz już jakieś pojęcie o tym, co chcesz, aby robił. Na potrzeby naszego przykładu utworzymy wtyczkę o nazwie "randplace", która zapewni nieco losową lokalizację każdego z Twoich wpisów. Nazwa wtyczki będzie służyć do znajdowania funkcji, które trzeba użyć i jest częścią nazwy każdej z tychfunkcji, więc dla bezpieczeństwa używaj tylko prostych znaków tekstowych. Po wybraniu nazwy wtyczki, utwórz katalog wewnątz 'addon', aby przechowywać tu pliki wtyczki. mkdir addon/randplace Teraz utwórz plik wtyczki. Musi mieć taką samą nazwę i jest to skrypt PHP, więc za pomocą swojego ulubionego edytora utwórz plik addon/randplace/randplace.php Pierwszą linią tego pliku musi być fraza * */ Te atrybuty będą widoczne dla administratora strony, gdy instaluje lub zarządza wtyczkami z panelu administracyjnego. Może być więcej autorów. W takim przypadku, po prostu dodaj kolejną linię zaczynającą się od "Autor:". Typowa wtyczka będzie miała co najmniej następujące funkcje: * pluginname_load() * pluginname_unload() W naszym przypadku nazwiemy je `randplace_load()` i `randplace_unload()`, bo taka jest nazwa naszej wtyczki. Te funkcje są wywoływane za każdym razem, gdy chcemy zainicjować wtyczkę lub usunąć ją z bieżącej strony internetowej. Również jeśli wtyczka wymaga rzeczy takich jak zmiana schematu bazy danych przed uruchomieniem jej po raz pierwszy, trzeba będzie umieścić poniższe funkcje: * pluginname_install() * pluginname_uninstall() Następnie omówimy **zaczepy**. Zaczepy (*ang. hooks*) to miejsca w kodzie $Projectname, do których można "podczepić" kod wtyczki, aby go tam wykonywać. Zwykle wykorzystuje się funkcję `pluginname_load()` do zarejestrowania "funkcji obsługi" dla potrzebnych zaczepów. Następnie, gdy zostanie wyzwolony którykolwiek z tych zaczepów, zostanie wywołany podpięty tam kod. Zarejestrujmy więc program obsługi zaczepów za pomocą funkcji `register_hook()`. Potrzebne są trzy argumenty. Pierwszy to nazwa zaczepu, który chcemy obsłużyć, drugi to nazwa pliku, który ma znaleźć naszą funkcję obsługi (ścieżka względem katalogu instalacyjnego $Projectname), a trzeci to nazwa funkcji. Stwórzmy więc teraz naszą funkcję `randplace_load()`. ``` function randplace_load() { register_hook('post_local', 'addon/randplace/randplace.php', 'randplace_post_hook'); register_hook('feature_settings', 'addon/randplace/randplace.php', 'randplace_settings'); register_hook('feature_settings_post', 'addon/randplace/randplace.php', 'randplace_settings_post'); } ``` Tak więc przechwycimy trzy zdarzenia: `post_local`, które jest wywoływane, gdy w systemie lokalnym pojawia się wpis, `feature_settings`, aby ustawić pewne preferencje dla naszej wtyczki, oraz `feature_settings_post`, aby przechowywać te ustawienia. Następnie utworzymy funkcję unload. Jest to łatwe, ponieważ wystarczy wyrejestrować nasze zaczepy. Wymaga to dokładnie tych samych argumentów. ``` function randplace_unload() { unregister_hook('post_local', 'addon/randplace/randplace.php', 'randplace_post_hook'); unregister_hook('feature_settings', 'addon/randplace/randplace.php', 'randplace_settings'); unregister_hook('feature_settings_post', 'addon/randplace/randplace.php', 'randplace_settings_post'); } ``` Zaczepy są wywoływane z dwoma argumentami. Pierwszą to zawsze $a, który jest naszą globalną strukturą aplikacji i zawiera ogromną ilość informacji o stanie przetwarzanego żądania HTTP; a także o tym kim jest przeglądający i jaki jest nasz stan logowania oraz aktualną zawartość strony internetowej, którą prawdopodobnie tworzymy. Drugi argument jest specyficzny dla zaczepu, który chce się wywołać. Zawiera informacje istotne dla tego konkretnego miejsca w programie i często pozwala na jego przegląd a nawet zmianę. Aby to zmienić, trzeba dodać zanak "&" do nazwy zmiennej, aby była przekazywana do funkcji przez odniesienie. W przeciwnym razie utworzona zostanie kopia i wszelkie wprowadzone zmiany zostaną utracone przy ponownym przetworzeniu zaczepu. Zwykle (ale nie zawsze) drugim argumentem jest nazwana tablica struktur danych. Dodajmy więc poniższy kod, aby zaimplementować nasz moduł obsługi zaczepu: ``` function randplace_post_hook($a, &$item) { /** * * W systemie lokalnym został wpisany jakiś element. * Będziemy wyszukiwać określonych elementów: * - Wpis napisany przez właściciela profilu * - Właściciel profilu musi zezwolić na naszą wtyczkę * */ logger('randplace invoked'); if(! local_channel()) /* nie zero jeśli zalogowany jest użytkownik systemu */ return; if(local_channel() != $item['uid']) /* Czy ta osoba jest właścicielem wpisu? */ return; if(($item['parent']) || (! is_item_normal($item))) { /* Jeśli element ma rodzica lub nie jest „normalny”, jest to komentarz lub coś innego, a nie wpis. */ return; } /* Pobranie osobistych ustawień konfiguracyjnych */ $active = get_pconfig(local_channel(), 'randplace', 'enable'); if(! $active) return; /** * * OK, wolno nam robić swoje. * Oto, co zamierzamy zrobić: * załadowanie listy nazw stref czasowych i użycie jej do wygenerowania listy miast na świecie. * Następnie wybierzemy losowo jedno z nich i umieścimy je w polu "location" wpisu. * */ $cities = array(); $zones = timezone_identifiers_list(); foreach($zones as $zone) { if((strpos($zone,'/')) && (! stristr($zone,'US/')) && (! stristr($zone,'Etc/'))) $cities[] = str_replace('_', ' ',substr($zone,strpos($zone,'/') + 1)); } if(! count($cities)) return; $city = array_rand($cities,1); $item['location'] = $cities[$city]; return; } ``` Teraz dodajmy nasze funkcje do ustawień preferencji tworzenia i przechowywania. ``` /** * * Wywołanie zwrotne z funkcji ustawień wpisu. * $post zawiera globalną tablicę $_POST. * Upewnimy się, że mamy ważne konto użytkownika * i że kliknięto tylko nasz własny przycisk submit * a jeśli tak, to ustawiamy ustawienia konfiguracyjne dla tego użytkownika. * */ function randplace_settings_post($a,$post) { if(! local_channel()) return; if($_POST['randplace-submit']) set_pconfig(local_channel(),'randplace','enable',intval($_POST['randplace'])); } /** * * Wywoływanie z formularza ustawień funkcjonalności. * Drugim argumentem jest w tym przypadku łańcuch, region treści HTML strony. * Dodanie własnych informacje o ustawieniach do tego łańcucha. * * Aby zapewnić jednolitość stron ustawień, stosujemy następującą konwencję *