Dystrybucja własnej wtyczki WordPress z prywatnego serwera
Po stworzeniu wtyczki przychodzi czas kiedy chcemy podzielić się nią ze światem. Możemy to zrobić za pośrednictwem oficjalnego kanału WordPress, albo ręcznie. Korzystając z oficjalnych kanałów dużo łatwiej będzie nam aktualizować wtyczkę.
W tym artykule pokaże jednak jak umieścić i aktualizować nasz skrypt na prywatnym serwerze. Jeżeli jeszcze nie masz serwera polecam SeoHost.
Tworzenie instalacyjnej wersji wtyczki
Jest to bardzo proste. Wtyczkę umieszczamy w katalogu z taką samą nazwą jak plik główny naszego pluginu i następnie pakujemy do formatu .zip
. Mamy więc taką strukturę katalogów i plików;
- wtyczka (katalog)
-- wtyczka.php
Następnie tak przygotowaną wtyczkę możemy dodać z menu Wtyczki w WordPress za pomocą przycisku „Wyślij wtyczkę na serwer”
Aktywacja, deaktywacja i deinstalacja
Po załadowaniu wtyczki możemy ją:
- aktywować (włączyć)
- deaktywować (wyłączyć)
- odinstalować
Każdą z tych operacji możemy obsłużyć, by np. w trakcie aktywowania wtyczki utworzyć tabele, a w trakcie jej odinstalowywania – usunąć je. Użytkownicy czasami wyłączają wtyczki np. w trakcie diagnozowania problemów, więc usuwanie wszystkiego w momencie deaktywacji może nie być pożądane. Dlatego takie operacje lepiej wykonywać w trakcie odinstalowywania pluginu.
Operacje związane z aktywacją i deaktywacją umieszczamy w pliku głównym modułu. Odinstalowywanie możemy umieścić w osobnym pliku uninstall.php
, który utworzymy w katalogu z wtyczką. Jest to specjalny plik, którego WordPress będzie szukał w momencie odinstalowywania pluginu.
Aktywacja
Do podpięcia funkcji aktywującej do WordPressa służy polecenie register_activation_hook
, które przyjmuje w pierwszym parametrze adres naszej wtyczki, a w drugim nazwę funkcji.. Spójrzmy na przykład:
function my_activation_function() {
// create tables if not exists
// other stuff
}
register_activation_hook ( __FILE__, "my_activation_function" );
__FILE__
zwraca ścieżkę do aktualnego pliku, czyli do naszej wtyczki.
Deaktywacja
Deaktywacja odbywa się podobnie, tyle że korzystamy z funkcji register_deactivation_hook
.
function my_deactivation_function() {
// do something
}
register_deactivation_hook ( __FILE__, "my_deactivation_function" );
Deinstalacja
Aby dodać czyszczenie wystarczy umieścić plik uninstall.php
, który WordPress automatycznie wyszuka w momencie odinstalowywania wtyczki. Zalecane jest również kontrolowanie czy plik nie został wywołany z zewnątrz, bo może być to spora luka w naszej aplikacji.
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) die;
// delete tables
// other cleans
Alternatywnie możemy również skorzystać z hooka register_uninstall_hook
.
Aktualizacja wtyczki
Do obsługi aktualizacji możemy skorzystać z filtra site_transient_update_plugins
. Spójrzmy na przykład.
function my_update_function ($transient) {
if ( empty( $transient->checked ) ) {
return $transient;
}
}
add_filter ( "site_transient_update_plugins", "my_update_function" );
Na początku naszej funkcji sprawdzamy czy istnieje obiekt checked
, który jest częścią obiektu transcient
, używanego przy aktualizacji. Obiekt ten zawiera informacje o zainstalowanych wtyczkach. Spójrzmy jak wyglądają dane dla popularnej wtyczki woocommerce
.
[woocommerce/woocommerce.php] => stdClass Object
(
[id] => w.org/plugins/woocommerce
[slug] => woocommerce
[plugin] => woocommerce/woocommerce.php
[new_version] => 8.0.2
[url] => https://wordpress.org/plugins/woocommerce/
[package] => https://downloads.wordpress.org/plugin/woocommerce.8.0.2.zip
[icons] => Array
(
[2x] => https://ps.w.org/woocommerce/assets/icon-256x256.gif?rev=2869506
[1x] => https://ps.w.org/woocommerce/assets/icon-128x128.gif?rev=2869506
)
[banners] => Array
(
[2x] => https://ps.w.org/woocommerce/assets/banner-1544x500.png?rev=2366418
[1x] => https://ps.w.org/woocommerce/assets/banner-772x250.png?rev=2366418
)
[banners_rtl] => Array
(
)
[requires] => 6.2
)
W przypadku grafiki możemy tutaj mieć też element default
w którym będzie np. ikona w skalowalnym formacie svg
.
Aby wymusić pojawienie się przycisku aktualizuj przy wtyczce, uzupełniamy obiekt transcient->response
w którym umieszczamy informacje o najnowszej wersji oraz link do jej pobrania.
$to_update = new stdClass();
$to_update->slug = $slug;
$to_update->plugin = plugin_basename( __FILE__ );
$to_update->new_version = $version;
$to_update->tested = $tested;
$to_update->package = $download_url;
$transient->response[ $to_update->plugin ] = $to_update;
return $transient;
Jak widzimy potrzebujemy kilku informacji dotyczących wtyczki. Przede wszystkim:
- najnowszej wersji wtyczki
- adresu do pobrania najnowszej wersji
- unikalnej nazwy (slug), którą nadajemy wtyczce
- na którym WordPress była testowana wtyczka
Informacja o wtyczce na zewnętrznym serwerze
Najprościej będzie te informacje umieścić na naszym serwerze zewnętrznym plik, który będziemy pobierać i sprawdzać czy dostępna jest najnowsza wersja. Stwórzmy plik w formacie json i umieśćmy go na zewnętrznym serwerze.
{
"slug":"nasza-wtyczka",
"version": "1.10",
"requires": "5.2",
"tested": "6.3",
"requires_php": "7.2",
"download_url": "http://adres_do_serwera/my_plugin.zip"
}
Dodaliśmy tutaj kilka innych użytecznych informacji:
- jaka wersja WordPress-a jest wymagana
- Na jakiej wersji była testowana wtyczka
- Jaka wersja PHP jest wymagana
Pobranie danych z serwera jest banalnie proste. Możemy skorzystać np. z file_get_contents()
.
$server_plugin_info_json = file_get_contents ("http://adres_serwera/my_plugin_info.json");
$server_plugin_info = json_decode ($erver_plugin_info_json, true);
Aktualna wersja wtyczki
Znamy już najnowszą wersję wtyczki, ale dalej musimy zweryfikować czy różni się ona od aktualnie zainstalowanej. Możemy to zrobić sprawdzając obiekt checked, albo pobierając te dane bezpośrednio z pliku wtyczki za pomocą funkcji
, która w parametrze przyjmuje adres do naszego pluginu. Funkcja zwraca tablicę z informacjami o nim, w tym element Version, który zawiera wersję.get_plugin_data
$current_version = get_plugin_data ( __FILE__ )['Version'];
Końcowy skrypt
Mamy już wszystko co niezbędne do stworzenia działającej aktualizacji.
function my_update_function ($transient) {
if ( empty( $transient->checked ) ) {
return $transient;
}
$server_plugin_info_json = file_get_contents ("http://adres_serwera/my_plugin_info.json");
$server_plugin_info = json_decode ($erver_plugin_info_json, true);
$current_version = get_plugin_data ( __FILE__ )['Version'];
if (
$server_plugin_info_json
&& version_compare ( $current_version, $server_plugin_info ['version'], '<' )
&& version_compare ( $server_plugin_info ['requires'], get_bloginfo( 'version' ), '<=' )
&& version_compare ( $server_plugin_info ['requires_php'], PHP_VERSION, '<' )
{
$to_update = new stdClass();
$to_update->slug = $server_plugin_info ['slug'];
$to_update->plugin = plugin_basename( __FILE__ );
$to_update->new_version = $server_plugin_info ['version'];
$to_update->tested = $server_plugin_info ['tested'];
$to_update->package = $server_plugin_info ['download_url'];
$transient->response[ $to_update->plugin ] = $to_update;
}
return $transient;
}
add_filter ( "site_transient_update_plugins", "my_update_function" );
Sprawdzamy czy udało się pobrać dane z serwera, a następnie czy obecna wersja różni się od najnowszej. Dodatkowo weryfikujemy PHP i wersję WordPress-a. Korzystamy przy tym z funkcji version_compare
. Jeżeli jest dostępna nowsza wersja to wtedy ustawiamy możliwość aktualizacji.
Podsumowanie
- Aby utworzyć „wersję do instalacji” wystarczy, że wrzucimy skrypt do katalogu z taką nazwą jak nazwa skryptu i spakujemy go do formatu
zip
. - Możemy wykonać dodatkowe operacje podczas aktywacji i deaktywacjii wtyczki podpinając funkcję do
register_activation_hook
lubregister_deactivation_hook
- Aby dodać operacje podczas odinstalowywania wtyczki możemy to zrobić w pliku
uninstall.php
w katalogu z wtyczką lub korzystamy z hookaregister_uninstall_hook
. - W celu wymuszenia aktualizacji skorzystamy z filtra
.site_transient_update_plugins
- Do pobrania informacji o aktualnej wtyczce możemy skorzystać z
get_plugin_data
. - Do porównania wersji wtyczki, php itp. możemy użyć funkcji
version_compare
.