Jangan Ulangi Diri Sendiri: Mengotomatiskan Tugas Berulang dengan WP-CLI

Diterbitkan: 2022-03-11

Pernahkah Anda menemukan diri Anda masuk ke area admin WordPress untuk memperbarui tema, plugin, dan inti WP? Tentu saja Anda punya. Pernahkah Anda ditanya, “Dapatkah Anda membuat/memperbarui/menghapus semua pengguna di file CSV ini?” Saya yakin Anda juga pernah mengalaminya. Sudahkah Anda mencoba memigrasi situs dan berharap ada plugin atau alat pihak ketiga yang dapat Anda jangkau untuk melakukan pekerjaan itu? Aku tahu aku punya!

Mengotomatiskan Tugas Berulang dengan WP-CLI

Ada alat yang sangat kuat yang tersedia untuk membantu Anda dengan tugas-tugas ini dan banyak lagi. Sebelum saya memberitahu Anda tentang hal itu, saya ingin membuat sebuah anekdot cepat.

Masalah: Dalam proyek baru-baru ini, ada beberapa tugas terprogram yang perlu saya ulangi secara teratur. Satu tugas khususnya melibatkan pembaruan izin tingkat pengguna berdasarkan bukti pembelian atau langganan tingkat keanggotaan. Jika perusahaan tidak dapat menemukan pembayaran dari pengguna untuk tingkat keanggotaan tertentu, mereka ingin tingkat keanggotaan dihapus dari pengguna. Mengapa ini diperlukan? Mungkin seorang anggota menghentikan langganan, tetapi suatu acara tidak diaktifkan, sehingga anggota tersebut masih memiliki akses meskipun mereka tidak membayarnya (ya ampun!). Atau mungkin seseorang sedang dalam penawaran percobaan, tetapi penawaran itu kedaluwarsa dan klien masih memiliki langganan (juga ya!).

Solusi: Alih-alih masuk ke panel admin dan secara manual menghapus ratusan (mungkin ribuan) langganan, saya memilih untuk menggunakan salah satu alat WordPress favorit saya, WP-CLI, yang memperbaiki masalah dalam beberapa penekanan tombol.

Dalam posting ini, saya ingin memperkenalkan Anda ke WP-CLI (dengan asumsi Anda belum berteman dekat), memandu Anda melalui perintah kustom sederhana yang saya tulis untuk situasi khusus ini, dan memberi Anda beberapa ide dan sumber daya untuk menggunakan WP-CLI di perkembangan Anda sendiri.

Apa itu WP-CLI?

Jika Anda belum pernah mendengar tentang WP-CLI sebelumnya, Anda tidak sendirian. Proyek itu, meski berumur beberapa tahun, tampaknya terbang di bawah radar WordPress untuk sementara waktu. Berikut penjelasan singkat tentang apa itu WP-CLI dan fungsinya dari situs resminya:

WP-CLI adalah seperangkat alat baris perintah untuk mengelola instalasi WordPress. Anda dapat memperbarui plugin, mengatur pemasangan multisitus, dan banyak lagi, tanpa menggunakan browser web.

Perintah berikut menunjukkan kepada Anda kekuatan WP-CLI di luar kotak:

  • wp plugin update --all memperbarui semua plugin yang dapat diperbarui.
  • wp db export mengekspor dump SQL dari database Anda.
  • wp media regenerate membuat ulang thumbnail untuk lampiran (misalnya, setelah Anda mengubah ukuran dalam tema Anda).
  • wp checksum core memverifikasi bahwa file inti WordPress belum dirusak.
  • wp search-replace mencari dan mengganti string dalam database.

Jika Anda menjelajahi lebih banyak perintah di sini, Anda akan melihat ada banyak perintah yang tersedia untuk tugas berulang yang dilakukan setiap pengembang WordPress atau pengelola situs setiap hari atau setiap minggu. Perintah-perintah ini telah menyelamatkan saya berjam-jam untuk menunjuk, mengklik, dan menunggu halaman dimuat ulang sepanjang tahun.

Apakah Anda yakin? Siap untuk memulai? Besar!

Anda harus menginstal WP-CLI dengan WordPress Anda (atau secara global di mesin lokal Anda). Jika Anda belum menginstal WP-CLI di lingkungan pengembangan lokal Anda, petunjuk penginstalan dapat ditemukan di situs web di sini. Jika Anda menggunakan Vary Vagrant Vagrants (VVV2), WP-CLI disertakan. Banyak penyedia hosting juga menyertakan WP-CLI di platform mereka. Saya akan menganggap Anda telah berhasil menginstal ini ke depan.

Menggunakan WP-CLI untuk Memecahkan Masalah

Untuk mengatasi masalah tugas yang berulang, kita perlu membuat perintah WP-CLI khusus tersedia untuk instalasi WordPress kita. Salah satu cara termudah untuk menambahkan fungsionalitas ke situs mana pun adalah dengan membuat plugin. Kami akan menggunakan plugin dalam hal ini karena tiga alasan utama:

  1. Kami akan dapat mematikan perintah khusus jika kami tidak membutuhkannya
  2. Kami dapat dengan mudah memperluas perintah dan sub-perintah kami sambil menjaga semuanya tetap modular.
  3. Kami dapat mempertahankan fungsionalitas di seluruh tema dan bahkan instalasi WordPress lainnya.

Membuat Plugin

Untuk membuat plugin, kita perlu menambahkan direktori ke direktori /plugins di direktori wp-content kita. Kita dapat memanggil direktori ini toptal-wpcli . Kemudian buat dua file di direktori itu:

  • index.php , yang seharusnya hanya memiliki satu baris kode: <?php // Silence is golden
  • plugin.php , di mana kode kita akan pergi (Anda dapat memberi nama file ini apa pun yang Anda inginkan.)

Buka file plugin.php dan tambahkan kode berikut:

 <?php /** * Plugin Name: TOPTAL WP-CLI Commands * Version: 0.1 * Plugin URI: https://n8finch.com/ * Description: Some rando wp-cli commands to make life easier... * Author: Nate Finch * Author URI: https://n8finch.com/ * Text Domain: toptal-wpcli * Domain Path: /languages/ * License: GPL v3 */ /** * NOTE: THIS PLUGIN FILE WILL NOT WORK IN PRODUCTION AS IS AND IS ONLY FOR DEMONSTRATION PURPOSES! * You can of course take the code and repurpose it:-). */ if ( !defined( 'WP_CLI' ) && WP_CLI ) { //Then we don't want to load the plugin return; }

Ada dua bagian untuk beberapa baris pertama ini.

Pertama, kita memiliki header plugin. Informasi ini ditarik ke halaman admin Plugin WordPress dan memungkinkan kita untuk mendaftarkan plugin kita dan mengaktifkannya. Hanya nama plugin yang diperlukan, tetapi kami harus menyertakan sisanya untuk siapa saja yang mungkin ingin menggunakan kode ini (serta diri kami di masa mendatang!).

Kedua, kami ingin memeriksa apakah WP-CLI didefinisikan. Artinya, kami memeriksa untuk melihat apakah konstanta WP-CLI ada. Jika tidak, kami ingin menyelamatkan dan tidak menjalankan plugin. Jika ada, kami jelas menjalankan sisa kode kami.

Di antara dua bagian ini, saya telah menambahkan catatan bahwa kode ini tidak boleh digunakan "sebagaimana adanya" dalam produksi, karena beberapa fungsi adalah pengganti untuk fungsi nyata. Jika Anda mengubah fungsi placeholder ini menjadi fungsi yang nyata dan aktif, jangan ragu untuk menghapus catatan ini.

Menambahkan Perintah Kustom

Selanjutnya, kami ingin memasukkan kode berikut:

 class TOPTAL_WP_CLI_COMMANDS extends WP_CLI_Command { function remove_user() { echo "\n\n hello world \n\n"; } } WP_CLI::add_command( 'toptal', 'TOPTAL_WP_CLI_COMMANDS' );

Blok kode ini melakukan dua hal untuk kita:

  1. Ini mendefinisikan kelas TOPTAL_WP_CLI_COMMANDS , tempat kita dapat meneruskan argumen.
  2. Ini memberikan perintah toptal ke kelas, jadi kita bisa menjalankannya dari baris perintah.

Sekarang, jika kita menjalankan wp toptal remove_user , kita melihat:

 $ wp toptal hello hello world

Ini berarti command toptal kami terdaftar dan remove_user kami berfungsi.

Menyiapkan Variabel

Karena kami memproses penghapusan pengguna secara massal, kami ingin menyiapkan variabel berikut:

 // Keep a tally of warnings and loops $total_warnings = 0; $total_users_removed = 0; // If it's a dry run, add this to the end of the success message $dry_suffix = ''; // Keep a list of emails for users we may want to double check $emails_not_existing = array(); $emails_without_level = array(); // Get the args $dry_run = $assoc_args['dry-run']; $level = $assoc_args['level']; $emails = explode( ',', $assoc_args['email'] );

Maksud dari masing-masing variabel adalah sebagai berikut:

  • total_warnings : Kami akan menghitung peringatan jika email tidak ada, atau jika email tidak terkait dengan tingkat keanggotaan yang kami hapus.
  • $total_users_removed : Kami ingin menghitung jumlah pengguna yang dihapus dalam proses (lihat peringatan di bawah).
  • $dry_suffix : Jika ini adalah proses kering, kami ingin menambahkan kata-kata ke pemberitahuan keberhasilan akhir.
  • $emails_not_existing : Menyimpan daftar email yang tidak ada.
  • $emails_without_level : Menyimpan daftar email yang tidak memiliki level yang ditentukan.
  • $dry_run : Sebuah boolean yang menyimpan apakah skrip melakukan dry run (true) atau tidak (false).
  • $level : Sebuah bilangan bulat yang mewakili level untuk diperiksa dan mungkin dihapus.
  • $email : Serangkaian email untuk diperiksa terhadap level yang diberikan. Kami akan mengulang melalui array ini

Dengan set variabel kami, kami siap untuk benar-benar menjalankan fungsi. Dengan gaya WordPress yang sebenarnya, kita akan menjalankan sebuah loop.

Menulis Fungsi Itu Sendiri

Kita mulai dengan membuat loop foreach untuk menggilir semua email dalam array $emails kita:

 // Loop through emails foreach ( $emails as $email ) { // code coming soon } // end foreach

Kemudian, kami menambahkan pemeriksaan bersyarat:

 // Loop through emails foreach ( $emails as $email ) { //Get User ID $user_id = email_exists($email); if( !$user_id ) { WP_CLI::warning( "The user {$email} does not seem to exist." ); array_push( $emails_not_existing, $email ); $total_warnings++; continue; } } // end foreach

Pemeriksaan ini memastikan kami memiliki pengguna terdaftar dengan email yang kami periksa. Ia menggunakan fungsi email_exists() untuk memeriksa apakah ada pengguna dengan email itu. Jika tidak menemukan pengguna dengan email itu, itu akan memberikan peringatan sehingga kami tahu di layar terminal kami bahwa email itu tidak ditemukan:

 $ wp toptal remove_user [email protected] --dry-run Warning: The user [email protected] does not seem to exist.

Email tersebut kemudian disimpan dalam array $emails_not_existing untuk ditampilkan nanti. Kemudian kami menambah total peringatan satu per satu dan melanjutkan loop ke email berikutnya.

Jika email memang ada, kami akan menggunakan variabel $user_id dan $level untuk memeriksa apakah pengguna memiliki akses ke level tersebut. Kami menyimpan nilai boolean yang dihasilkan dalam variabel $has_level :

 // Loop through emails foreach ( $emails as $email ) { //Get User ID $user_id = email_exists($email); if( !$user_id ) { WP_CLI::warning( "The user {$email} does not seem to exist." ); array_push( $emails_not_existing, $email ); $total_warnings++; continue; } // Check membership level. This is a made up function, but you could write one or your membership plugin probably has one. $has_level = function_to_check_membership_level( $level, $user_id ); } // end foreach

Seperti kebanyakan fungsi dalam contoh ini, function_to_check_membership_level() ini dibuat, tetapi sebagian besar plugin keanggotaan harus memiliki fungsi pembantu untuk memberi Anda informasi ini.

Sekarang, kita akan beralih ke tindakan utama: menghapus level dari pengguna. Kami akan menggunakan struktur if/else , yang terlihat seperti ini:

 foreach ( $emails as $email ) { // Previous code here... // Check membership level. This is a made up function, but you could write one or your membership plugin probably has one. $has_level = function_to_check_membership_level( $level, $user_id ); if ( $has_level ) { if ( !$dry_run ) { // Deactivate membership level. This is a made up function, but you could write one or your membership plugin probably has one. function_to_deactivate_membership_level( $level, $user_id, 'inactive' ); } WP_CLI::success( "Membership canceled for {$email}, Level {$level} removed" . PHP_EOL ); $total_users_removed++; } else { WP_CLI::warning( "The user {$email} does not have Level = {$level} membership." ); array_push( $emails_without_level, $email ); $total_warnings++; } // We could echo something here to show that things are processing... } // end foreach

Jika nilai $has_level adalah “truthy”, artinya pengguna memiliki akses ke level keanggotaan, kami ingin menjalankan fungsi untuk menghapus level tersebut. Dalam contoh ini, kita akan menggunakan function_to_deactivate_membership_level() untuk melakukan tindakan ini.

Namun, sebelum kami benar-benar menghapus level dari pengguna, kami ingin menyertakan fungsi itu dalam pemeriksaan bersyarat untuk melihat apakah ini benar-benar sebuah dry-run . Jika ya, kami tidak ingin menghapus apa pun, hanya melaporkan yang kami lakukan. Jika ini bukan dry-run , maka kami akan melanjutkan dan menghapus level dari pengguna, mencatat pesan sukses kami ke terminal, dan melanjutkan pengulangan melalui email.

Sebaliknya, jika nilai $has_level adalah “falsey”, artinya pengguna tidak memiliki akses ke tingkat keanggotaan, kami ingin mencatat peringatan ke terminal, mendorong email ke array $emails_without_level , dan melanjutkan looping melalui email.

Menyelesaikan dan Melaporkan

Setelah loop selesai, kami ingin mencatat hasil kami ke konsol. Jika ini adalah proses kering, kami ingin mencatat pesan tambahan ke konsol:

 if ( $dry_run ) { $dry_suffix = 'BUT, nothing really changed because this was a dry run:-).'; }

$dry-suffix ini akan ditambahkan ke peringatan dan pemberitahuan sukses yang kita log berikutnya.

Selesai, kami ingin mencatat hasil kami sebagai pesan sukses dan peringatan kami sebagai pesan peringatan. Kami akan melakukannya seperti ini:

 WP_CLI::success( "{$total_users_removed} User/s been removed, with {$total_warnings} warnings. {$dry_suffix}" ); if ( $total_warnings ) { $emails_not_existing = implode(',', $emails_not_existing); $emails_without_level = implode(',', $emails_without_level); WP_CLI::warning( "These are the emails to double check and make sure things are on the up and up:" . PHP_EOL . "Non-existent emails: " . $emails_not_existing . PHP_EOL . "Emails without the associated level: " . $emails_without_level . PHP_EOL ); }

Perhatikan bahwa kami menggunakan metode pembantu WP_CLI::success dan WP_CLI::warning . Ini disediakan oleh WP-CLI untuk mencatat informasi ke konsol. Anda dapat dengan mudah mencatat string, yang kami lakukan di sini, termasuk variabel $total_users_removed , $total_warnings , dan $dry_suffix .

Terakhir, jika kami mendapatkan peringatan apa pun selama runtime skrip, kami ingin mencetak informasi itu ke konsol. Setelah menjalankan pemeriksaan bersyarat, kita mengubah variabel array $emails_not_existing dan $emails_without_level menjadi variabel string. Kami melakukan ini agar kami dapat mencetaknya ke konsol menggunakan metode WP_CLI::warning helper.

Menambahkan Deskripsi

Kita semua tahu bahwa komentar berguna bagi orang lain dan diri kita di masa depan, kembali ke kode kita berminggu-minggu, berbulan-bulan, atau bahkan bertahun-tahun kemudian. WP-CLI menyediakan antarmuka deskripsi singkat (shortdesc) dan deskripsi panjang (longdesc) yang memungkinkan kita untuk membubuhi keterangan perintah kita. Kami akan menempatkan di bagian atas perintah kami, setelah kelas TOPTAL_WP_CLI_COMMANDS didefinisikan:

 /** * Remove a membership level from a user * * ## OPTIONS * --level=<number> * : Membership level to check for and remove * * --email=<email> * : Email of user to check against * * [--dry-run] * : Run the entire search/replace operation and show report, but don't save changes to the database. * * ## EXAMPLES * * wp toptal remove_user --level=5 [email protected],[email protected], [email protected] --dry-run * * @when after_wp_load */

Dalam longdesc, kami menentukan apa yang kami harapkan akan diterima oleh perintah kustom kami. Sintaks untuk shortdesc dan longdesc adalah Markdown Extra. Di bawah bagian ## OPTIONS , kami mendefinisikan argumen yang kami harapkan akan diterima. Jika argumen diperlukan, kami membungkusnya dengan < > , dan jika opsional, kami membungkusnya dalam [ ] .

Opsi ini divalidasi saat perintah dijalankan; misalnya, jika kami mengabaikan parameter email yang diperlukan, kami mendapatkan kesalahan berikut:

 $ wp toptal remove_user --level=5 --dry-run Error: Parameter errors: missing --email parameter (Email of user to check against)

Bagian ## EXAMPLES menyertakan contoh tampilan perintah saat dipanggil.

Perintah kustom kami sekarang selesai. Anda dapat melihat inti akhir di sini.

Peringatan dan Ruang untuk Peningkatan

Penting untuk meninjau pekerjaan yang telah kami lakukan di sini untuk melihat bagaimana kode dapat ditingkatkan, diperluas, dan difaktorkan ulang. Ada banyak area perbaikan untuk skrip ini. Berikut adalah beberapa pengamatan tentang perbaikan yang dapat dilakukan.

Kadang-kadang, saya menemukan skrip ini tidak akan menghapus semua pengguna yang dicatatnya sebagai "dihapus." Ini kemungkinan besar karena skrip berjalan lebih cepat daripada yang dapat dieksekusi oleh kueri. Pengalaman Anda mungkin berbeda, tergantung pada lingkungan dan penyiapan tempat skrip dijalankan. Cara cepat untuk mengatasinya adalah dengan menjalankan berulang kali dengan input yang sama; itu pada akhirnya akan nol dan melaporkan bahwa tidak ada pengguna yang telah dihapus.

Skrip dapat ditingkatkan untuk menunggu dan memvalidasi bahwa pengguna telah dihapus sebelum mencatat pengguna sebagai benar-benar dihapus. Ini akan memperlambat eksekusi skrip, tetapi akan lebih akurat, dan Anda hanya perlu menjalankannya sekali.

Demikian pula, jika ada kesalahan yang ditemukan seperti ini, skrip dapat memunculkan kesalahan untuk memperingatkan bahwa level belum dihapus dari pengguna.

Area lain untuk meningkatkan skrip adalah mengizinkan beberapa level sekaligus dihapus dari satu alamat email. Skrip dapat mendeteksi secara otomatis jika ada satu atau lebih level dan satu atau lebih email yang harus dihapus. Saya diberi file CSV berdasarkan level, jadi saya hanya perlu menjalankan satu level dalam satu waktu.

Kami juga dapat memfaktorkan ulang beberapa kode untuk menggunakan operator ternary alih-alih pemeriksaan bersyarat yang lebih verbose yang kami miliki saat ini. Saya telah memilih untuk membuat ini lebih mudah dibaca demi demonstrasi, tetapi jangan ragu untuk membuat kode Anda sendiri.

Pada langkah terakhir, alih-alih mencetak email ke konsol pada langkah terakhir, kami juga dapat mengekspornya secara otomatis ke file CSV atau teks biasa

Terakhir, tidak ada pemeriksaan untuk memastikan kita mendapatkan bilangan bulat untuk variabel $level atau email atau daftar email yang dipisahkan koma dalam variabel $emails . Saat ini, jika seseorang memasukkan string alih-alih bilangan bulat, atau nama login pengguna alih-alih email, skrip tidak akan berfungsi (dan tidak menimbulkan kesalahan). Cek untuk bilangan bulat dan email dapat ditambahkan.

Ide untuk Otomatisasi Lebih Lanjut dan Bacaan Lebih Lanjut

Seperti yang Anda lihat, bahkan dalam kasus penggunaan khusus ini, WP-CLI cukup fleksibel dan cukup kuat untuk membantu Anda menyelesaikan pekerjaan dengan cepat dan efisien. Anda mungkin bertanya-tanya pada diri sendiri, “Bagaimana saya bisa mulai menerapkan WP-CLI dalam alur pengembangan harian dan mingguan saya?”

Ada beberapa cara Anda dapat menggunakan WP-CLI. Berikut adalah beberapa favorit saya:

  • Perbarui tema, plugin, dan inti WP tanpa harus masuk ke panel admin.
  • Ekspor database untuk cadangan atau lakukan dump SQL cepat jika saya ingin menguji kueri SQL.
  • Migrasi situs WordPress.
  • Instal situs WordPress baru dengan data dummy atau pengaturan suite plugin khusus.
  • Jalankan checksum pada file inti untuk memastikan file tersebut tidak disusupi. (Sebenarnya ada proyek yang sedang berlangsung untuk memperluas ini ke tema dan plugin di repo WP.)
  • Tulis skrip Anda sendiri untuk memeriksa, memperbarui, dan memelihara host situs (yang saya tulis di sini).

Kemungkinan dengan WP-CLI hampir tidak terbatas. Berikut adalah beberapa sumber untuk membuat Anda terus maju:

  • Situs WP-CLI utama: http://wp-cli.org
  • Perintah WP-CLI: https://developer.wordpress.org/cli/commands/
  • Blog WP-CLI Resmi: https://make.wordpress.org/cli/
  • Buku Pegangan WP-CLI: https://make.wordpress.org/cli/handbook/
  • Ke WooCommerce? Lihat WC-CLI: https://github.com/woocommerce/woocommerce/wiki/WC-CLI-Overview#woocommerce-commands
  • Wawancara Podcast dengan Daniel Bachhuber, pengelola proyek: https://howibuilt.it/episode-28-daniel-bachhuber-wp-cli/