Membuat Plugin WordPress Yang Menggunakan Service API, “Dari Soup Sampai Nut”

Diterbitkan: 2022-03-10
Ringkasan cepat Sejumlah besar API yang tersedia untuk umum menyediakan layanan yang kuat untuk memperluas fungsionalitas aplikasi kami. WordPress adalah CMS yang sangat dinamis dan fleksibel yang mendukung segala hal mulai dari blog pribadi kecil hingga situs web e-niaga besar dan semua yang ada di antaranya. Bagian dari apa yang membuat WordPress begitu serbaguna adalah sistem pluginnya yang kuat , yang membuatnya sangat mudah untuk menambahkan fungsionalitas. Kami akan membahas bagaimana saya membuat GitHub Pipeline, sebuah plugin yang memungkinkan Anda menampilkan data dari GitHub API di halaman WordPress menggunakan shortcode. Saya akan memberikan contoh spesifik dan cuplikan kode, tetapi pertimbangkan teknik yang dijelaskan di sini sebagai cetak biru cara menggunakan API layanan apa pun dengan plugin. Kita akan mulai dari awal, tetapi tingkat keakraban dengan WordPress dan pengembangan plugin diasumsikan, dan kita tidak akan menghabiskan waktu untuk topik pemula, seperti menginstal WordPress atau Composer.

Semakin banyak jumlah API yang tersedia untuk umum menyediakan layanan yang kuat untuk memperluas fungsionalitas aplikasi kami. WordPress adalah CMS yang sangat dinamis dan fleksibel yang mendukung segala hal mulai dari blog pribadi kecil hingga situs web e-niaga besar dan semua yang ada di antaranya. Bagian dari apa yang membuat WordPress begitu serbaguna adalah sistem pluginnya yang kuat , yang membuatnya sangat mudah untuk menambahkan fungsionalitas.

Kami akan membahas bagaimana saya membuat GitHub Pipeline, sebuah plugin yang memungkinkan Anda menampilkan data dari GitHub API di halaman WordPress menggunakan shortcode. Saya akan memberikan contoh spesifik dan cuplikan kode, tetapi pertimbangkan teknik yang dijelaskan di sini sebagai cetak biru cara menggunakan API layanan apa pun dengan plugin.

Bacaan Lebih Lanjut tentang SmashingMag:

  • Esensi WordPress: Cara Membuat Plugin WordPress
  • Cara Menyebarkan Plugin WordPress Dengan GitHub Menggunakan Transien
  • Tiga Pendekatan Untuk Menambahkan Bidang yang Dapat Dikonfigurasi Ke Plugin Anda

Kita akan mulai dari awal, tetapi tingkat keakraban dengan WordPress dan pengembangan plugin diasumsikan, dan kita tidak akan menghabiskan waktu untuk topik pemula, seperti menginstal WordPress atau Composer.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

Kamu akan membutuhkan:

  • lingkungan PHP, dengan instalasi baru WordPress;
  • akun GitHub (atau penyedia API lain jika Anda ingin berimprovisasi);
  • Komposer (disarankan).

Memilih API

Langkah pertama dalam menulis plugin semacam ini adalah memilih API. Dalam tutorial ini, kita akan menggunakan GitHub API. Jika Anda berpikir untuk menggunakan API lain, pertimbangkan beberapa faktor penting yang dapat memengaruhi seberapa menguntungkan proyek Anda nantinya.

Salah satu hal pertama yang saya lihat adalah ketelitian dan kualitas dokumentasi API. Jika jarang atau ketinggalan zaman, bersiaplah untuk menghabiskan waktu memilah-milah kode sumber untuk menjawab pertanyaan Anda sendiri. Juga, pertimbangkan seberapa matang API dan seberapa bertanggung jawab penyedia telah membuat versinya. Tidak ada yang lebih buruk daripada menginvestasikan waktu dalam menciptakan sesuatu yang hebat, hanya untuk itu rusak karena perubahan pada API upstream. Cari sistem versi di URL titik akhir.

 // good https://api.stable.com/v1/user/ // danger https://api.dodgy.com/user/

Dengan risiko menyatakan yang sudah jelas, pemrograman terhadap API pihak ketiga melibatkan hubungan kepercayaan, dan tidak semua API dibuat sama.

Belanja untuk Perpustakaan

Merek mapan sering mendistribusikan perpustakaan atau SDK untuk mempermudah bekerja dengan API mereka. Jika tidak demikian, ingatlah untuk meneliti apakah orang lain telah menulis perpustakaan sebelum Anda pergi dan menemukan kembali kemudi. Google dan GitHub adalah dua tempat yang bagus untuk memulai penelitian Anda. Jumlah bintang atau garpu di GitHub merupakan indikasi yang baik tentang seberapa efektif perpustakaan. Usia komit terbaru dan/atau jumlah masalah terbuka merupakan indikasi seberapa aktif itu dipertahankan. Dalam kasus saya, saya beruntung menemukan PHP GitHub API yang bagus, oleh KNP Labs.

Menulis Sendiri Dengan Guzzle

Jika tidak ada perpustakaan yang memuaskan untuk penyedia Anda, Anda tetap tidak boleh memulai dari awal karena alat seperti Guzzle membuat bekerja dengan permintaan HTTP menjadi lebih mudah. Guzzle membungkus pustaka cURL PHP dan menghilangkan banyak masalah yang biasanya terkait dengan mengonfigurasi dan membuat permintaan secara manual. Bahkan jika Anda hanya membuat satu atau dua permintaan, saya tetap menyarankan untuk menggunakannya karena itu akan membuat kode Anda lebih kuat, dan menginstalnya dengan Komposer adalah hal yang mudah.

Menyiapkan Plugin

Kita akan mulai dengan kerangka dasar plugin WordPress minimal, sebuah direktori dengan dua file. Memilih nama folder yang deskriptif dan unik penting untuk menghindari konflik dengan plugin lain. Jika nama plugin Anda agak umum, pertimbangkan untuk menambahkan awalan yang unik.

 github-api/ readme.txt github-api.php

readme.txt berisi data meta untuk plugin Anda yang akan muncul di wordpress.org jika Anda memutuskan untuk mempublikasikannya di sana. Baca tentang memublikasikan plugin WordPress di dokumentasi, atau lihat contoh lengkap readme.txt.

File PHP juga berisi beberapa meta data di header yang akan digunakan untuk menampilkan info tentang plugin Anda di dashboard. Mulailah dengan tajuk yang terlihat seperti ini:

 <?php /** Plugin Name: GitHub API description: >- Add GitHub project information using shortcode Version: 1.0 Author: Your Name License: GPLv2 or later Text Domain: github-api */

Untuk alasan keamanan, ada baiknya juga untuk menolak akses langsung ke file, seperti ini:

 defined( 'ABSPATH' ) or die( 'No script kiddies please!' );

Pada titik ini, plugin tidak akan melakukan apa pun, tetapi ketika Anda menyalin file ke wp-content/plugins , itu akan muncul di daftar plugin dan Anda harus dapat mengaktifkannya.

Halaman plugin dasbor WordPress
Halaman plugin dasbor WordPress. (Lihat versi besar)

Selanjutnya, kami ingin menyertakan pustaka yang akan menangani permintaan API. Dalam contoh kode berikut, kami menyertakan PHP GitHub API KNP Labs, tetapi Anda dapat menyertakan ketergantungan apa pun dengan mengganti knplabs/github-api dengan paket yang Anda gunakan.

 $ cd wp-content/plugins/github-api $ composer require knplabs/github-api

Sekarang, struktur file Anda akan terlihat sebagai berikut:

 github-api/ composer.json composer.lock github-api.php readme.txt vendor/

Sekarang file sudah ada, kita perlu meminta vendor/autoload.php yang dibuat saat Anda menginstalnya.

 require_once 'vendor/autoload.php';

Jika semuanya telah diatur dengan benar, Anda harus dapat membuat instance kelas dari perpustakaan tanpa kesalahan fatal yang terjadi.

 $testing = new \Github\Client();

Tetapi ini hanyalah cara cepat untuk menguji apakah dependensi Anda tersedia. Saya sarankan mendefinisikan kelas baru yang memperluas perpustakaan.

 class MyGithub extends \Github\Client {};

Ini tidak penting, tetapi membuat kode Anda lebih fleksibel dalam beberapa cara. Cara yang paling jelas adalah Anda dapat mengubah atau menambahkan fungsionalitas baru jika perlu. Tapi itu juga membuat hidup lebih mudah jika Anda ingin berpindah perpustakaan di masa mendatang, karena Anda harus membuat perubahan hanya di satu tempat, bukan di seluruh kode Anda.

Kode Pendek WordPress

Sekarang saatnya untuk menyiapkan kode pendek pertama kita, yang merupakan cuplikan khusus yang memungkinkan Anda menghasilkan konten dengan menempatkannya di pos atau halaman. Jika Anda benar-benar baru mengenal kode pendek atau Anda ingin pemahaman yang lebih mendalam tentang cara kerjanya, lihat dokumentasi kode pendek resmi. Dalam contoh saya, saya akan menampilkan daftar masalah GitHub di mana pun penulis menempatkan kode pendek ini: [github_issues]

Seperti yang kita lakukan sebelumnya, mari kita mulai dengan contoh minimal untuk memastikan kode pendek terdaftar dengan benar sebelum kita mengerjakan panggilan API.

 function github_issues_func( $atts ) { return "Hello world!"; } add_shortcode( "github_issues", "github_issues_func" );

Sekarang, jika Anda memublikasikan halaman yang berisi [github_issues] , Anda akan melihat "Halo dunia" saat mengunjungi halaman tersebut. Sekarang setelah ini berfungsi, mari siapkan panggilan API.

Di bagian sebelumnya, kami mengatur pemuatan otomatis untuk perpustakaan GitHub kami dan mendefinisikan kelas kami sendiri untuk memperluasnya. Sekarang, kita dapat mulai menggunakannya untuk membuat panggilan API. Jadi, kami akan menambahkannya ke fungsi panggilan balik kode pendek. Sebagai bukti konsep, mari ambil semua masalah di repositori GitHub Pipeline. Dokumentasi untuk metode ini tersedia.

 function github_issues_func( $atts ) { // Instantiate our class $gh = new MyGithub(); // Make the API call to get issues, passing in the GitHub owner and repository $issues = $gh->api('issue')->all('TransitScreen', 'wp-github-pipeline'); // Handle the case when there are no issues if ( empty($issues) ) return "<strong>" . __("No issues to show", 'githup-api') . "</strong>"; // We're going to return a string. First, we open a list. $return = "<ul>"; // Loop over the returned issues foreach( $issues as $issue ) { // Add a list item for each issue to the string // (Feel free to get fancier here) // Maybe make each one a link to the issue issuing $issue['url] ) $return .= "<li>{$issue['title']}</li>"; } // Don't forget to close the list $return .= "</ul>"; return $return; } add_shortcode( 'github_issues', 'github_issues_func' );

Sekarang Anda seharusnya dapat melihat halaman yang sama yang kami gunakan di atas untuk menguji kode pendek, dan kali ini Anda akan melihat daftar masalah yang tidak berurutan. Tapi tunggu! Sebelum melanjutkan, mari kita buat satu optimasi agar kode kita lebih mudah untuk diuji. (Anda sedang menguji, kan?!) Alih-alih menggunakan new dalam fungsi kita untuk membuat instance kelas library GitHub, mari kita berikan sebagai parameter dan buat instance hanya jika kita harus melakukannya.

 function github_issues_func( $atts, $gh=null ) { // Conditionally instantiate our class $gh = ( $gh ) ? $gh : new MyGithub(); …

Modifikasi ini menyerupai pola injeksi ketergantungan, yang membuat fungsi kita lebih mudah untuk diuji. Pengujian unit WordPress berada di luar cakupan tutorial ini, tetapi mudah untuk melihat bagaimana versi baru ini memudahkan kami untuk meneruskan data API "palsu" ke fungsi tersebut sehingga pernyataan pengujian kami tahu persis apa yang diharapkan.

Apa yang telah kami buat sejauh ini baik dan bagus untuk proyek internal yang hanya akan digunakan pada satu repositori, tetapi akan jauh lebih berguna jika pengguna dapat mengonfigurasi repositori untuk mengambil masalah. Mari kita atur itu.

Pertama, kita akan menggunakan hook WordPress untuk mendaftarkan halaman pengaturan baru kita, dan fungsi callback akan menentukan label dan judul menu. Kami akan menggunakan pendekatan inkremental yang sama untuk membuatnya bekerja.

 // Register the menu. add_action( "admin_menu", "gh_plugin_menu_func" ); function gh_plugin_menu_func() { add_submenu_page( "options-general.php", // Which menu parent "GitHub", // Page title "GitHub", // Menu title "manage_options", // Minimum capability (manage_options is an easy way to target administrators) "github", // Menu slug "gh_plugin_options" // Callback that prints the markup ); } // Print the markup for the page function gh_plugin_options() { if ( !current_user_can( "manage_options" ) ) { wp_die( __( "You do not have sufficient permissions to access this page." ) ); } echo "Hello world!"; }

Sekarang Anda seharusnya dapat masuk ke dasbor dan melihat menu GitHub baru di bawah "Pengaturan" dan kemudian klik untuk melihat halaman pengaturan kosong dengan "Halo dunia!"

Halaman plugin WordPress kosong
Halaman plugin WordPress kosong. (Lihat versi besar)

Selanjutnya, kita akan mengganti Hello word dengan markup form yang sebenarnya. Saya akan memberi Anda contoh barebone yang dapat Anda gaya sesedikit atau sebanyak yang Anda suka.

 ?> <form method="post" action="<?php echo admin_url( 'admin-post.php'); ?>"> <input type="hidden" name="action" value="update_github_settings" /> <h3><?php _e("GitHub Repository Info", "github-api"); ?></h3> <p> <label><?php _e("GitHub Organization:", "github-api"); ?></label> <input class="" type="text" name="gh_org" value="<?php echo get_option('gh_org'); ?>" /> </p> <p> <label><?php _e("GitHub repository (slug):", "github-api"); ?></label> <input class="" type="text" name="gh_repo" value="<?php echo get_option('gh_repo'); ?>" /> </p> <input class="button button-primary" type="submit" value="<?php _e("Save", "github-api"); ?>" /> </form> <?php

Kelas CSS yang saya sertakan cocok dengan yang digunakan oleh inti WordPress, yang merupakan cara yang bagus untuk membuat halaman opsi kustom Anda terlihat layak tanpa usaha tambahan.

Halaman pengaturan WordPress khusus dengan gaya dasar
Halaman pengaturan WordPress kustom dengan gaya dasar. (Lihat versi besar)

Ada dua hal penting yang harus dipahami tentang formulir ini. Pertama, titik akhir yang dikirimkannya harus /wp-admin/admin-post.php . Anda dapat membuat hardcode jalur ini, tetapi jika situs web dipasang di subdirektori, itu tidak akan berfungsi. Jadi, kami menggunakan admin_url() untuk membuatnya secara dinamis.

Kedua, perhatikan input tersembunyi dengan nama action . Bidang ini adalah cara WordPress mengetahui apa yang harus dilakukan dengan permintaan posting yang dikirimkan oleh formulir. value sesuai dengan nama kait tindakan yang akan kita gunakan untuk mengatur fungsi panggilan balik. Nama tindakan yang akan kita kaitkan adalah nilai ini, diawali dengan admin post . Jadi, dalam kasus kami, kami perlu menambahkan ini:

 add_action( 'admin_post_update_github_settings', 'github_handle_save' );

Saya menemukan ini sebagai salah satu aspek yang lebih unik dan kurang intuitif dalam membuat menu administrasi khusus, tetapi begitu Anda terbiasa, itu cukup mudah. Seperti yang mungkin sudah Anda duga, parameter kedua dari add_action() adalah nama fungsi panggilan balik kami yang sebenarnya akan menyimpan nilai ke database.

 function github_handle_save() { // Get the options that were sent $org = (!empty($_POST["gh_org"])) ? $_POST["gh_org"] : NULL; $repo = (!empty($_POST["gh_repo"])) ? $_POST["gh_repo"] : NULL; // Validation would go here // Update the values update_option( "gh_repo", $repo, TRUE ); update_option("gh_org", $org, TRUE); // Redirect back to settings page // The ?page=github corresponds to the "slug" // set in the fourth parameter of add_submenu_page() above. $redirect_url = get_bloginfo("url") . "/wp-admin/options-general.php?page=github&status=success"; header("Location: ".$redirect_url); exit; }

Contohnya juga cukup minim. Dalam pengaturan produksi, Anda mungkin ingin menambahkan beberapa validasi. Juga, dalam contoh ini, kami secara otomatis meneruskan kembali status=success ke URL. Markup formulir belum benar-benar menggunakannya. Untuk menampilkan pesan sukses secara kondisional, tambahkan sesuatu seperti berikut di atas formulir di gh_plugin_options() :

 if ( isset($_GET['status']) && $_GET['status']=='success') { ?> <div class="updated notice is-dismissible"> <p><?php _e("Settings updated!", "github-api"); ?></p> <button type="button" class="notice-dismiss"> <span class="screen-reader-text"><?php _e("Dismiss this notice.", "github-api"); ?></span> </button> </div> <?php }

Jika Anda menambahkan validasi, gunakan pola yang sama ini untuk mengirimkan kembali status dan pesan yang berbeda sehingga pengguna mengetahui jika dan mengapa pengiriman formulir mereka gagal.

Sekarang Anda seharusnya dapat menyimpan nilai pemilik dan repositori baru. Uji dengan memasukkan pemilik dan repositori proyek publik apa pun di GitHub. Langkah terakhir adalah kembali ke fungsi panggilan balik kode pendek github_issues_func() dan mengganti pemilik hardcode dan nilai repositori.

 … $issues = $gh->api("issue")->all(get_option("gh_org"), get_option("gh_repo")); …

Setelah ini ada, kunjungi kembali halaman tempat Anda menambahkan kode pendek. Anda sekarang akan melihat masalah dari proyek mana pun yang Anda tetapkan.

Putaran Bonus: Otentikasi OAuth 2.0

Pendekatan yang kami gunakan di atas berfungsi dengan baik untuk repositori publik, tetapi bagaimana jika kami ingin menggunakan plugin ini dengan repositori pribadi yang memerlukan otentikasi? GitHub API mengautentikasi menggunakan protokol OAuth 2.0, yang akan Anda temui saat bekerja dengan API paling populer saat ini. Alur kerja OAuth 2.0 dasar berjalan seperti ini:

  1. Anda mendaftarkan aplikasi (terkadang disebut "klien") dengan penyedia dan menerima ID unik dan kunci rahasia.
  2. Aplikasi Anda membuat permintaan ke titik akhir autentikasi penyedia, meneruskan kredensial di atas serta URL pengalihan yang digunakan penyedia untuk mengalihkan permintaan kembali ke titik akhir aplikasi Anda.
  3. Pengguna kemudian diminta untuk menerima permintaan akses Anda. Jika ya, penyedia menggunakan URL yang Anda kirim dengan permintaan untuk mengarahkan pengguna kembali ke aplikasi Anda, bersama dengan kode sementara.
  4. Aplikasi Anda menangkap kode ini dan kemudian membuat permintaan kedua, meneruskan kode ini kembali ke penyedia. Penyedia merespons dengan token akses, yang kemudian digunakan aplikasi Anda untuk mengautentikasi dengan penyedia.

Kita akan mulai dengan mendaftarkan aplikasi dengan GitHub. Seperti kebanyakan API populer, bagian ini terletak di area pengembang situs web.

Halaman pendaftaran aplikasi baru GitHub
Halaman pendaftaran aplikasi baru GitHub. (Lihat versi besar)

Yang paling penting di sini adalah URL panggilan balik otorisasi. URL pengalihan yang diteruskan pada langkah ketiga harus cocok dengan apa yang Anda masukkan di sini, atau menyertakannya. Jadi, selama pengembangan, saya biasanya masuk ke halaman beranda situs web. Dengan cara ini, aplikasi saya dapat mengarahkan ulang ke jalur mana pun.

Selanjutnya, kami akan menambahkan formulir kedua ke halaman pengaturan kami, di gh_plugin_options() , untuk mengirimkan ID klien dan rahasia aplikasi.

 <form method="post" action="<?php echo admin_url( 'admin-post.php'); ?>"> <input type="hidden" name="action" value="oauth_submit" /> <h3>Oauth 2.0</h3> <p> <label><?php _e("GitHub Application Client ID:", "github-api"); ?></label> <input class="" type="text" name="client_id" value="<?php echo get_option('client_id')?>" /> </p> <p> <label><?php _e("GitHub Application Client Secret:", "github-api"); ?></label> <input class="" type="password" name="client_secret" value="<?php echo get_option('client_secret')?>" /> </p> <input class="button button-primary" type="submit" value="<?php _e("Authorize", "github-api"); ?>" /> </form>

Untuk mempermudah hidup, saya akan menggunakan Penyedia GitHub untuk Klien OAuth 2.0 oleh The League of Extraordinary Packages. Jadi, pertama, mari kita gunakan Composer lagi untuk menambahkan ketergantungan:

 composer require league/oauth2-github

Perhatikan bahwa perpustakaan GitHub dari KNP Labs juga memiliki dukungan OAuth 2.0 bawaan. Jadi, dalam contoh spesifik saya, ini agak berlebihan. Tetapi saya ingin memperkenalkan perpustakaan ini karena itu milik rangkaian perpustakaan klien OAuth 2.0 khusus penyedia yang semuanya memperluas kerangka kerja yang sama yang dikelola oleh League of Extraordinary Packages yang perkasa. Anda dapat melihat daftar lengkap penyedia yang didukung atau membaca petunjuk tentang cara memperluas kerangka kerja untuk mendukung penyedia baru.

Mari buat fungsi untuk meminta dan menyimpan token saat pengguna mengirimkan formulir. Karena GitHub adalah salah satu penyedia yang sudah mendukung, saya dapat menyalin contoh di dokumentasinya hanya dengan beberapa modifikasi.

 function handle_oauth() { // If the form was just submitted, save the values // (Step 1 above) if ( isset($_POST["client_id"]) && isset($_POST["client_secret"]) ) { update_option( "client_id", $_POST["client_id"], TRUE ); update_option("client_secret", $_POST["client_secret"], TRUE); } // Get the saved application info $client_id = get_option("client_id"); $client_secret = get_option("client_secret"); if ($client_id && $client_secret) { $provider = new League\OAuth2\Client\Provider\Github([ "clientId" => $client_id, "clientSecret" => $client_secret, "redirectUri" => admin_url("options-general.php?page=github"), ]); } // If this is a form submission, start the workflow // (Step 2) if (!isset($_GET["code"]) && $_SERVER["REQUEST_METHOD"] === "POST") { // If we don't have an authorization code, then get one $authUrl = $provider->getAuthorizationUrl(); $_SESSION["oauth2state"] = $provider->getState(); header("Location: ".$authUrl); exit; // Check given state against previously stored one to mitigate CSRF attack // (Step 3 just happened and the user was redirected back) } elseif (empty($_GET["state"]) || ($_GET["state"] !== $_SESSION["oauth2state"])) { unset($_SESSION["oauth2state"]); exit("Invalid state"); } else { // Try to get an access token (using the authorization code grant) // (Step 4) $token = $provider->getAccessToken("authorization_code", [ "code" => $_GET["code"] ]); // Save the token for future use update_option( "github_token", $token->getToken(), TRUE ); } }

Dan, seperti yang kita lakukan dengan formulir lain, kita perlu menambahkan kait tindakan agar fungsi dipanggil saat formulir disimpan.

 add_action( "admin_post_oauth_submit", "handle_oauth" );

Menyimpan formulir sekarang akan mengirim Anda ke halaman otorisasi penyedia API. Setelah otorisasi, aplikasi Anda dapat menggunakan token yang disimpan untuk meminta data dari repositori pribadi yang dapat Anda akses. Pustaka yang saya gunakan oleh KNP Labs memiliki metode praktis untuk ini.

 $gh = new MyGithub(); $gh->authenticate( get_option("github_token"), NULL, Github\Client::AUTH_HTTP_TOKEN);

Perpustakaan akan berbeda dalam hal tepatnya bagaimana mereka menangani otentikasi, tetapi dengan satu atau lain cara, Anda akan meneruskan token, yang kemudian akan membuat permintaan yang diautentikasi atas nama pengguna.

Kesimpulan

Kami telah membahas banyak hal, dan saya telah mencoba untuk menjaga contoh seminimal mungkin sehingga alur kerja keseluruhan tetap jelas. Kode sumber lengkap dari tutorial ini tersedia. Saya harap Anda sekarang memiliki pemahaman yang jelas tentang bagian-bagian bergerak yang terlibat dalam pembuatan plugin WordPress yang menggunakan API layanan pihak ketiga, dan semoga Anda terinspirasi untuk menulis plugin API WordPress Anda sendiri.

Catatan Akhir

  • Codex WordPress (dokumentasi)
  • GitHub API (dokumentasi)
  • OAuth 2.0 (dokumentasi)
  • Komposer (dokumentasi)
  • Liga Paket Luar Biasa
  • Dokumentasi Guzzle