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 get_plugin_data, która w parametrze przyjmuje adres do naszego pluginu. Funkcja zwraca tablicę z informacjami o nim, w tym element Version, który zawiera wersję.

$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

  1. Aby utworzyć „wersję do instalacji” wystarczy, że wrzucimy skrypt do katalogu z taką nazwą jak nazwa skryptu i spakujemy go do formatu zip.
  2. Możemy wykonać dodatkowe operacje podczas aktywacji i deaktywacjii wtyczki podpinając funkcję do register_activation_hook lub register_deactivation_hook
  3. Aby dodać operacje podczas odinstalowywania wtyczki możemy to zrobić w pliku uninstall.php w katalogu z wtyczką lub korzystamy z hooka register_uninstall_hook.
  4. W celu wymuszenia aktualizacji skorzystamy z filtra site_transient_update_plugins.
  5. Do pobrania informacji o aktualnej wtyczce możemy skorzystać z get_plugin_data.
  6. Do porównania wersji wtyczki, php itp. możemy użyć funkcji version_compare.