() translation by (you can also view the original English article)
WordPress telah memudahkan plugin untuk digunakan untuk publik. Cukup letakkan plugin Anda di repositori plugin WordPress dan itu dapat dengan mudah ditemukan oleh orang-orang dari dalam dashboard mereka.
Mungkin salah satu fitur terbaik dari repositori adalah membuatnya mudah untuk memperbarui plugin dari dalam dashboard. Pemberitahuan pembaruan ditampilkan di dalam dasbor, dan melakukan pembaruan semudah mengklik tombol Update Now.
Tapi bagaimana kalau Anda ingin meng-host plugin sendiri? Fitur pembaruan yang mudah tidak akan tersedia jika Anda meng-host plugin Anda di luar repo plugin WordPress. Pengguna Anda juga tidak akan diberitahu tentang pembaruan yang tersedia.
Artikel ini akan mengajarkan Anda bahwa dengan sedikit pengkodean kreatif, Anda dapat meng-host plugin WordPress Anda sendiri di GitHub sambil tetap mempertahankan fitur pembaruan otomatis.
Mengapa Host Plugin Anda di GitHub?
Mungkin ada beberapa alasan mengapa Anda ingin menghosting plugin Anda di luar repositori plugin WordPress. Salah satu batasan utama yang diberikan repositori adalah Anda harus melisensikan plugin Anda sebagai GPLv2. Saya tidak akan membahas perincian lisensi, tetapi singkatnya itu berarti bahwa siapa pun dapat berbagi pekerjaan Anda. Jadi jika Anda ingin menjual plugin Anda, maka hosting itu di repositori pribadi GitHub sekarang menjadi opsi yang dapat Anda pertimbangkan.
Namun, karena cara WordPress dibangun, hosting plugin Anda di GitHub akan menonaktifkan pembaruan otomatis untuk plugin kami. Untuk memahami mengapa hal ini terjadi, kita harus memahami bagaimana WordPress menangani pembaruan plugin.
Bagaimana WordPress Memperbarui Plugin
Pertama, mari kita selidiki bagaimana WordPress melakukan pembaruan plugin untuk mendapatkan pemahaman yang lebih baik tentang mengapa plugin yang di-host sendiri tidak dapat memiliki pembaruan otomatis
WordPress secara berkala memeriksa repositori WordPress untuk pembaruan plugin yang Anda instal. Ia menerima banyak informasi tentang setiap plugin seperti versi terbarunya dan URL paket plugin. Inilah yang biasanya kita lihat di halaman admin plugin ketika kami diberitahu tentang pembaruan:



Ketika kami mengklik tautan View version x.x details, WordPress melakukan pencarian lain di repo plugin. Kali ini ia mendapat informasi lebih rinci tentang plugin seperti deskripsi, changelog, versi WordPress yang diuji, dan banyak lagi. Informasi ini ditunjukkan kepada kami di lightbox:



Terakhir, ketika tautan Update Now diklik, paket plugin yang diperbarui diunduh dan diinstal.
Jadi mengapa pembaruan otomatis tidak berfungsi untuk plugin yang di-host-sendiri? Itu karena WordPress mencoba menemukannya di repositori plugin WordPress dan tidak dapat menemukannya di sana!
Rencana permainan
Rencana kami adalah untuk mengaktifkan pembaruan otomatis dengan plugin kami yang dihosting GitHub.
Berikut daftar apa yang perlu kita lakukan untuk membuatnya bekerja:
- Kami membutuhkan cara untuk menyebarkan pembaruan plugin di GitHub.
- Kami harus menunjukkan pemberitahuan pembaruan versi plugin,
- Akan lebih baik untuk menampilkan detail plugin ketika tautan View version x.x details diklik.
- Kami juga ingin berhasil menginstal pembaruan plugin ketika tautan update now diklik,
Bagaimana untuk mengeksekusi rencana
Kami akan menggunakan beberapa filter WordPress agar kami dapat mengimplementasikan rencana permainan kami. Ini adalah:
-
pre_set_site_transient_update_plugins
. Filter ini dipanggil ketika WordPress mencoba memeriksa pembaruan plugin. -
plugins_api
. Yang ini digunakan ketika WordPress menunjukkan detail pembaruan dari plugin. -
iupgrader_post_install
. Terakhir, ini dipanggil setelah plugin berhasil diinstal.
Kami akan menghubungkan ke filter ini, kemudian mendorong data kami ke dalam hasil untuk membuat WordPress berpikir bahwa plugin kami ada di repositori plugin WordPress. Data yang akan kami masukkan akan berasal dari repo GitHub kami, dan harus meniru data yang diberikan oleh repositori plugin.
Menyiapkan Proyek GitHub
Sebelum kita melanjutkan dengan pengkodean, mari kita bicara tentang GitHub dan bagaimana kita akan menggunakannya untuk memberikan data yang kita butuhkan untuk memberi makan WordPress.
Anda akan memerlukan repositori GitHub pribadi atau publik. Repo Anda harus berisi semua file plugin Anda, dan bukan salinan terkompresi dari plugin Anda.
Kami akan menggunakan fitur keren dari GitHub yang disebut Rilis.



Hal yang baik tentang rilis adalah ia mendapatkan basis kode saat ini di repositori dan membuat file zip yang dapat diunduh untuk setiap rilis spesifik. Kami dapat memberi tahu WordPress untuk mengunduh file zip ini ketika memperbarui plugin kami.
Hal baik lainnya tentang Rilis adalah kita bisa memasukkan detail pembaruan plugin kita di catatan rilis. Kami kemudian dapat menguraikan ini dan menampilkannya di lightbox WordPress untuk rincian pembaruan plugin. Kami dapat melangkah lebih jauh dan bahkan mengizinkan markdown GitHub untuk changelog kami.



Saat tiba waktunya untuk menyebarkan pembaruan ke plugin kami, ikuti pemformatan pada gambar di atas saat Anda membuat rilis baru:
- Tag Name: Versi plugin (hanya nomornya)
- Release notes: Deskripsi pembaruan
Membuat Kelas Updater kami
Sekarang saatnya untuk kode plugin kami!
Pertama, kami membuat titik awal untuk kelas kami:
1 |
class BFIGitHubPluginUpdater { |
2 |
|
3 |
private $slug; // plugin slug |
4 |
private $pluginData; // plugin data |
5 |
private $username; // GitHub username |
6 |
private $repo; // GitHub repo name |
7 |
private $pluginFile; // __FILE__ of our plugin |
8 |
private $githubAPIResult; // holds data from GitHub |
9 |
private $accessToken; // GitHub private repo token |
10 |
|
11 |
function __construct( $pluginFile, $gitHubUsername, $gitHubProjectName, $accessToken = '' ) { |
12 |
add_filter( "pre_set_site_transient_update_plugins", array( $this, "setTransitent" ) ); |
13 |
add_filter( "plugins_api", array( $this, "setPluginInfo" ), 10, 3 ); |
14 |
add_filter( "upgrader_post_install", array( $this, "postInstall" ), 10, 3 ); |
15 |
|
16 |
$this->pluginFile = $pluginFile; |
17 |
$this->username = $gitHubUsername; |
18 |
$this->repo = $gitHubProjectName; |
19 |
$this->accessToken = $accessToken; |
20 |
}
|
21 |
|
22 |
// Get information regarding our plugin from WordPress
|
23 |
private function initPluginData() { |
24 |
// code here
|
25 |
}
|
26 |
|
27 |
// Get information regarding our plugin from GitHub
|
28 |
private function getRepoReleaseInfo() { |
29 |
// code here
|
30 |
}
|
31 |
|
32 |
// Push in plugin version information to get the update notification
|
33 |
public function setTransitent( $transient ) { |
34 |
// code here
|
35 |
return $transient; |
36 |
}
|
37 |
|
38 |
// Push in plugin version information to display in the details lightbox
|
39 |
public function setPluginInfo( $false, $action, $response ) { |
40 |
// code ehre
|
41 |
return $response; |
42 |
}
|
43 |
|
44 |
// Perform additional actions to successfully install our plugin
|
45 |
public function postInstall( $true, $hook_extra, $result ) { |
46 |
// code here
|
47 |
return $result; |
48 |
}
|
49 |
}
|
Ini adalah struktur kelas yang akan kita gunakan. Kami hanya mendefinisikan semua fungsi yang akan kami gunakan dan membuat hook filter kami. Kelas ini tidak melakukan apa-apa pada saat ini, kecuali untuk menetapkan nilai ke properti kelas.
Argumen Konstruktor
Agar kelas kita dapat dieksekusi, kita perlu beberapa argumen:
-
$pluginFile
: Kami akan memanggil kelas ini dari skrip plugin utama kami, ini harus memiliki nilai__FILE__
. Kami akan mendapatkan detail tentang plugin kami nanti. -
$gitHubUsername
: Nama pengguna GitHub Anda -
$gitHubProjectName
: Nama repositori GitHub Anda -
$accessToken
: Token akses yang memungkinkan kita melihat detail repo GitHub pribadi. Jika proyek Anda dihosting di repo GitHub publik, biarkan ini kosong.
Sekarang mari kita isi fungsi kelas kita dengan beberapa kode.
Fungsi initPluginData
Ini adalah fungsi paling sederhana di kelas kami. Kami akan membutuhkan slug plugin kami dan informasi lain di seluruh skrip, jadi kami melakukan panggilan yang diperlukan dalam fungsi untuk kenyamanan.
1 |
$this->slug = plugin_basename( $this->pluginFile ); |
2 |
$this->pluginData = get_plugin_data( $this->pluginFile ); |
Fungsi getRepoReleaseInfo
Fungsi ini adalah tentang berkomunikasi dengan GitHub untuk mendapatkan informasi rilis kami. Kami akan menggunakan API GitHub untuk mendapatkan detail mengenai rilis terbaru kami. Kemudian simpan semua yang kita dapatkan di properti githubAPIResult
kami untuk diproses di masa depan.
Filter pre_set_site_transient_update_plugins
dipanggil dua kali oleh WordPress, sekali ketika memeriksa pembaruan plugin, lalu yang lain setelah mendapat hasil. Karena kita akan menggunakan fungsi ini di filter itu, kita akan menanyakan API GitHub dua kali. Kami hanya perlu mendapatkan informasi dari GitHub sekali:
1 |
// Only do this once
|
2 |
if ( ! empty( $this->githubAPIResult ) ) { |
3 |
return; |
4 |
}
|
Selanjutnya, kami akan menggunakan API GitHub untuk mendapatkan informasi tentang rilis kami:
1 |
// Query the GitHub API
|
2 |
$url = "https://api.github.com/repos/{$this->username}/{$this->repo}/releases"; |
3 |
|
4 |
// We need the access token for private repos
|
5 |
if ( ! empty( $this->accessToken ) ) { |
6 |
$url = add_query_arg( array( "access_token" => $this->accessToken ), $url ); |
7 |
}
|
8 |
|
9 |
// Get the results
|
10 |
$this->githubAPIResult = wp_remote_retrieve_body( wp_remote_get( $url ) ); |
11 |
if ( ! empty( $this->githubAPIResult ) ) { |
12 |
$this->githubAPIResult = @json_decode( $this->githubAPIResult ); |
13 |
}
|
Terakhir, kami hanya akan menyimpan data untuk rilis plugin terbaru:
1 |
// Use only the latest release
|
2 |
if ( is_array( $this->githubAPIResult ) ) { |
3 |
$this->githubAPIResult = $this->githubAPIResult[0]; |
4 |
}
|
Sekarang kita bisa mendapatkan data plugin dari GitHub. Kami akan menguraikan data ini dalam fungsi berikutnya.
Fungsi setTransitent
Fungsi ini dipanggil ketika WordPress memeriksa pembaruan plugin. Tugas kami di sini adalah menggunakan data rilis GitHub kami untuk memberikan informasi untuk pembaruan plugin kami.
Hal pertama yang kami lakukan adalah memeriksa apakah WordPress telah memeriksa pembaruan plugin sebelumnya. Jika sudah, maka kita tidak perlu menjalankan sisa fungsi lagi.
1 |
// If we have checked the plugin data before, don't re-check
|
2 |
if ( empty( $transient->checked ) ) { |
3 |
return $transient; |
4 |
}
|
Selanjutnya, kita akan mendapatkan informasi plugin yang akan kita gunakan:
1 |
// Get plugin & GitHub release information
|
2 |
$this->initPluginData(); |
3 |
$this->getRepoReleaseInfo(); |
Setelah memanggil kedua fungsi ini, kita dapat memeriksa versi plugin lokal kita dari versi (nama tag) yang ditemukan di GitHub. Kita dapat menggunakan fungsi version_compare
PHP yang nyaman untuk membandingkan dua nilai:
1 |
// Check the versions if we need to do an update
|
2 |
$doUpdate = version_compare( $this->githubAPIResult->tag_name, $transient->checked[$this->slug] ); |
Terakhir, ada pembaruan plugin yang tersedia, kita perlu meminta admin untuk menampilkan pemberitahuan pembaruan. Kami melakukan ini dengan mengisi variabel $transient
dengan informasi plugin kami yang diperbarui.
1 |
// Update the transient to include our updated plugin data
|
2 |
if ( $doUpdate == 1 ) { |
3 |
$package = $this->githubAPIResult->zipball_url; |
4 |
|
5 |
// Include the access token for private GitHub repos
|
6 |
if ( !empty( $this->accessToken ) ) { |
7 |
$package = add_query_arg( array( "access_token" => $this->accessToken ), $package ); |
8 |
}
|
9 |
|
10 |
$obj = new stdClass(); |
11 |
$obj->slug = $this->slug; |
12 |
$obj->new_version = $this->githubAPIResult->tag_name; |
13 |
$obj->url = $this->pluginData["PluginURI"]; |
14 |
$obj->package = $package; |
15 |
$transient->response[$this->slug] = $obj; |
16 |
}
|
17 |
|
18 |
return $transient; |
Setelah fungsi ini memproses informasi GitHub kami, admin kami akan dapat menampilkan pemberitahuan di halaman admin plugin:



Fungsi setPluginInfo
Tujuan fungsi ini adalah untuk mengumpulkan perincian tentang plugin yang diperbarui dari catatan rilis. Semua informasi ini akan ditampilkan di dalam lightbox ketika tautan View versi x.x details diklik.
Pertama, mari kita dapatkan informasi plugin kami:
1 |
// Get plugin & GitHub release information
|
2 |
$this->initPluginData(); |
3 |
$this->getRepoReleaseInfo(); |
Selanjutnya kita periksa apakah sudah waktunya menampilkan sesuatu atau tidak. Kami dapat memeriksa apakah kami mencoba memuat informasi untuk plugin kami saat ini dengan memeriksa slug
:
1 |
// If nothing is found, do nothing
|
2 |
if ( empty( $response->slug ) || $response->slug != $this->slug ) { |
3 |
return false; |
4 |
}
|
Untuk menampilkan detail plugin kami, kami perlu menambahkan informasi plugin kami secara manual ke variabel $response
, biasanya variabel ini akan diisi dengan hasil dari repositori plugin WordPress:
1 |
// Add our plugin information
|
2 |
$response->last_updated = $this->githubAPIResult->published_at; |
3 |
$response->slug = $this->slug; |
4 |
$response->plugin_name = $this->pluginData["Name"]; |
5 |
$response->version = $this->githubAPIResult->tag_name; |
6 |
$response->author = $this->pluginData["AuthorName"]; |
7 |
$response->homepage = $this->pluginData["PluginURI"]; |
8 |
|
9 |
// This is our release download zip file
|
10 |
$downloadLink = $this->githubAPIResult->zipball_url; |
11 |
|
12 |
// Include the access token for private GitHub repos
|
13 |
if ( !empty( $this->accessToken ) ) { |
14 |
$downloadLink = add_query_arg( |
15 |
array( "access_token" => $this->accessToken ), |
16 |
$downloadLink
|
17 |
);
|
18 |
}
|
19 |
$response->download_link = $downloadLink; |
Sejauh ini kami telah menambahkan detail plugin kami, tetapi kami belum mem-parsing catatan rilis kami dari rilis GitHub kami. Mari kita periksa apa yang kita miliki di catatan rilis kami:



Dalam catatan rilis, kami telah menetapkan tiga detail tentang rilis kami: changelog kami, diikuti oleh versi WordPress minimum yang disyaratkan, kemudian versi WordPress terbaru yang diuji plugin. Kami akan menguraikan teks ini dan mengekstraksi nilai-nilai ini.
Karena kita hosting plugin kita di GitHub, alangkah baiknya jika kita dapat memiliki kemampuan untuk menggunakan markdown GitHub dalam catatan rilis kami. Saya akan menggunakan kelas PHP yang disebut ParseDown untuk mengonversi teks markdown ke HTML:
1 |
// We're going to parse the GitHub markdown release notes, include the parser
|
2 |
require_once( plugin_dir_path( __FILE__ ) . "Parsedown.php" ); |
Kami juga akan membuat tab di lightbox untuk membuatnya sesuai dengan bagaimana plugin yang dihosting repositori WordPress menampilkan informasinya. Satu untuk deskripsi plugin dan lainnya untuk changelog kami:
1 |
// Create tabs in the lightbox
|
2 |
$response->sections = array( |
3 |
'description' => $this->pluginData["Description"], |
4 |
'changelog' => class_exists( "Parsedown" ) |
5 |
? Parsedown::instance()->parse( $this->githubAPIResult->body ) |
6 |
: $this->githubAPIResult->body |
7 |
);
|
Akhirnya kita akan mengekstraksi nilai-nilai untuk kebutuhan dan diuji:
1 |
// Gets the required version of WP if available
|
2 |
$matches = null; |
3 |
preg_match( "/requires:\s([\d\.]+)/i", $this->githubAPIResult->body, $matches ); |
4 |
if ( ! empty( $matches ) ) { |
5 |
if ( is_array( $matches ) ) { |
6 |
if ( count( $matches ) > 1 ) { |
7 |
$response->requires = $matches[1]; |
8 |
}
|
9 |
}
|
10 |
}
|
11 |
|
12 |
// Gets the tested version of WP if available
|
13 |
$matches = null; |
14 |
preg_match( "/tested:\s([\d\.]+)/i", $this->githubAPIResult->body, $matches ); |
15 |
if ( ! empty( $matches ) ) { |
16 |
if ( is_array( $matches ) ) { |
17 |
if ( count( $matches ) > 1 ) { |
18 |
$response->tested = $matches[1]; |
19 |
}
|
20 |
}
|
21 |
}
|
22 |
|
23 |
return $response; |
Fungsi postInstall
Fungsi terakhir ini kita akan berurusan dengan melakukan proses tambahan yang kita butuhkan untuk menginstal plugin kita sepenuhnya setelah diunduh.
Saat membuat rilis untuk repo GitHub kami, secara otomatis membuat file zip untuk rilis spesifik itu. Nama file untuk file zip dihasilkan oleh GitHub dengan format reponame-tagname.zip. Ini juga berisi direktori tempat file plugin kami berada. Demikian pula, nama direktori untuk ini juga mengikuti format reponame-tagname.
Biasanya, ketika WordPress mengunduh dan membuka ritsleting arsip plugin, nama direktori plugin tidak berubah. Jika Anda direktori plugin adalah my-awesome-plugin, setelah menghapus file plugin lama dan membuka yang diperbarui, direktori Anda masih akan bernama my-awesome-plugin. Tetapi karena GitHub mengubah nama direktori plugin kami setiap kali kami meluncurkan rilis, WordPress tidak akan dapat menemukan plugin kami. Itu masih dapat menginstalnya, tetapi itu tidak akan dapat mengaktifkannya kembali. Kami dapat memperbaiki masalah ini dengan mengganti nama direktori baru agar sesuai dengan yang lama.
Hal pertama yang pertama:
1 |
// Get plugin information
|
2 |
$this->initPluginData(); |
Selanjutnya kita harus memeriksa apakah plugin kita saat ini diaktifkan, sehingga kita dapat mengaktifkannya kembali setelahnya:
1 |
// Remember if our plugin was previously activated
|
2 |
$wasActivated = is_plugin_active( $this->slug ); |
Sekarang kami mengganti nama direktori plugin kami yang diperbarui agar sesuai dengan yang lama. Kami menggunakan fungsi move
di sini, tetapi karena kami menentukan direktori yang sama, itu akan seperti mengganti nama:
1 |
// Since we are hosted in GitHub, our plugin folder would have a dirname of
|
2 |
// reponame-tagname change it to our original one:
|
3 |
global $wp_filesystem; |
4 |
$pluginFolder = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . dirname( $this->slug ); |
5 |
$wp_filesystem->move( $result['destination'], $pluginFolder ); |
6 |
$result['destination'] = $pluginFolder; |
Langkah terakhir adalah mengaktifkan kembali plugin:
1 |
// Re-activate plugin if needed
|
2 |
if ( $wasActivated ) { |
3 |
$activate = activate_plugin( $this->slug ); |
4 |
}
|
5 |
|
6 |
return $result; |
Memanggil Kelas Updater GitHub Kami
Sekarang setelah kelas selesai, yang harus dilakukan adalah memanggilnya di file plugin utama kami:
1 |
require_once( 'BFIGitHubPluginUploader.php' ); |
2 |
if ( is_admin() ) { |
3 |
new BFIGitHubPluginUpdater( __FILE__, 'myGitHubUsername', "Repo-Name" ); |
4 |
}
|
Mencoba
Hanya itu! Cukup sertakan kelas ini dan panggil di plugin Anda, dan itu harus mulai memeriksa pembaruan secara otomatis.
Untuk menguji apakah itu berfungsi, buat rilis baru untuk repo GitHub Anda dan ikuti panduan yang dinyatakan sebelumnya:



Setelah membuat rilis, Anda dapat memaksa WordPress untuk memeriksa pembaruan dengan mengeklik tombol refresh yang ditemukan di bilah admin.
Kesimpulan
Saya harap Anda mempelajari satu atau dua hal tentang cara kerja WordPress dan bagaimana seluruh proses pembaruan plugin dilakukan. Anda dapat mengunduh skrip lengkap dari tautan unduhan di bagian atas artikel ini.
Saya harap Anda menikmati artikel ini. Saya sangat menghargai umpan balik apapun, komentar dan saran. Berbagi pemikiran Anda di bawah ini!