Thứ Tư, 28 tháng 6, 2017

AUTOMATICALLY INSTALL PLUGINS WITH THEMES FOR WORDPRESS

Well, now that is completely possible with a new class that I have built on top of a lot of WordPress APIs. With some help from Gary Jones, the TGM_Plugin_Activation class is now available for WordPress theme authors and users everywhere!
***UPDATE***
Version 2.0 now has an API for theme authors to hook into to use the class, eliminating the need to change the code within the class. Check out the details below!

HOW IT WORKS

The TGM_Plugin_Activation class works by taking a set a key => value pairs from a multidimensional array and processes them to do one of two things:
  1. Automatically install a plugin that comes pre-packaged with the theme
  2. Automatically download the .zip file from the WordPress Plugin Repository and install it
In either case, this new class can handle multiple instances of both, which means that you can include/prompt to download as many plugins as needed!
On theme activation, users are prompted with admin notices that certain plugins are required for the theme. Users can then click the links that take them to a page where forms are prepared for them to submit.
The UI is very familiar and intuitive because it follows suit with the rest of the WordPress admin UI. Users can then hit the submit button that installs the plugin. You can even have plugins be downloaded and installed from the WordPress Plugin Repository!
The TGM_Plugin_Activation class uses the same methods as WordPress itself uses to download, install, upgrade and activate plugins.

HOW TO INCLUDE THE TGM_PLUGIN_ACTIVATION CLASS WITH YOUR THEME

Take a look at the following code (taken from the example.php file included with the class):
<?php
/**
* Include the TGM_Plugin_Activation class.
*/
require_once dirname( __FILE__ ) . '/class-tgm-plugin-activation.php';
add_action( 'tgmpa_register', 'my_theme_register_required_plugins' );
/**
* Register the required plugins for this theme.
*
* In this example, we register two plugins - one included with the TGMPA library
* and one from the .org repo.
*
* The variable passed to tgmpa_register_plugins() should be an array of plugin
* arrays.
*
* This function is hooked into tgmpa_init, which is fired within the
* TGM_Plugin_Activation class constructor.
*/
function my_theme_register_required_plugins() {
/**
* Array of plugin arrays. Required keys are name and slug.
* If the source is NOT from the .org repo, then source is also required.
*/
$plugins = array(
/** This is an example of how to include a plugin pre-packaged with a theme */
array(
'name' => 'TGM Example Plugin', // The plugin name
'slug' => 'tgm-example-plugin', // The plugin slug (typically the folder name)
'source' => get_stylesheet_directory() . '/lib/plugins/tgm-example-plugin.zip', // The plugin source
'required' => false,
),
/** This is an example of how to include a plugin from the WordPress Plugin Repository */
array(
'name' => 'Edit Howdy',
'slug' => 'edit-howdy',
),
);
/** Change this to your theme text domain, used for internationalising strings */
$theme_text_domain = 'tgmpa';
/**
* Array of configuration settings. Uncomment and amend each line as needed.
* If you want the default strings to be available under your own theme domain,
* uncomment the strings and domain.
* Some of the strings are added into a sprintf, so see the comments at the
* end of each line for what each argument will be.
*/
$config = array(
/*'domain' => $theme_text_domain, // Text domain - likely want to be the same as your theme. */
/*'default_path' => '', // Default absolute path to pre-packaged plugins */
/*'menu' => 'install-my-theme-plugins', // Menu slug */
'strings' => array(
/*'page_title' => __( 'Install Required Plugins', $theme_text_domain ), // */
/*'menu_title' => __( 'Install Plugins', $theme_text_domain ), // */
/*'instructions_install' => __( 'The %1$s plugin is required for this theme. Click on the big blue button below to install and activate %1$s.', $theme_text_domain ), // %1$s = plugin name */
/*'instructions_activate' => __( 'The %1$s is installed but currently inactive. Please go to the <a href="%2$s">plugin administration page</a> page to activate it.', $theme_text_domain ), // %1$s = plugin name, %2$s = plugins page URL */
/*'button' => __( 'Install %s Now', $theme_text_domain ), // %1$s = plugin name */
/*'installing' => __( 'Installing Plugin: %s', $theme_text_domain ), // %1$s = plugin name */
/*'oops' => __( 'Something went wrong with the plugin API.', $theme_text_domain ), // */
/*'notice_can_install' => __( 'This theme requires the %1$s plugin. <a href="%2$s"><strong>Click here to begin the installation process</strong></a>. You may be asked for FTP credentials based on your server setup.', $theme_text_domain ), // %1$s = plugin name, %2$s = TGMPA page URL */
/*'notice_cannot_install' => __( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', $theme_text_domain ), // %1$s = plugin name */
/*'notice_can_activate' => __( 'This theme requires the %1$s plugin. That plugin is currently inactive, so please go to the <a href="%2$s">plugin administration page</a> to activate it.', $theme_text_domain ), // %1$s = plugin name, %2$s = plugins page URL */
/*'notice_cannot_activate' => __( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', $theme_text_domain ), // %1$s = plugin name */
/*'return' => __( 'Return to Required Plugins Installer', $theme_text_domain ), // */
),
);
tgmpa( $plugins, $config );
}
view rawgistfile1.php hosted with ❤ by GitHub
This may seem like a lot of code, but don’t let it scare you. Most of it is commenting to help you understand what each part does and how the API interacts with the class.
First you need to include the class for use within your functions.php file. This is done by the require_once line. You should amend the path so that it targets wherever you decide to place the class within your theme directory structure.
The crux of the API is the tgmpa_register() hook and the tgmpa() function. Your plugin information and configurations are added within a function that is added to the tgmpa_register hook. There are three variables for you to play with: $plugins$config and $theme_text_domain.
The $plugins variables is required for you to fill out to include your plugins. The variable takes multiple arrays of arguments for your plugins. The keys ‘name’ and ‘slug’ are required for both pre-packaged and repo plugins. If you plugin is pre-packaged, the ‘source’ key is also required. The ‘required’ key is a boolean that will soon be used to determine whether your plugin is required or simply recommended. You can leave this out for now as it will not be active until a future update.
The $theme_text_domain is for localization. You set your own text domain here so that the strings used by the class can be localized along with your other theme text strings.
The $config variable allows you to set the theme text domain, the default absolute path to your pre-packaged plugins, the menu slug for the install plugins page, and an array of strings to customize admin notices and other messages to your theme users. Refer to the example.php file to learn how you can customize these for your theme.

A LOOK AT WHAT’S INSIDE

This automatic plugin installer class makes use of quite a few of WordPress’ own classes. Specifically, this class uses WP_Filesystem, Plugin_Upgrader, Plugin_Skin_Installer and WP_Error. This class also makes use of the plugins_api function as well for preparation for the plugin install and activation.
Unfortunately, none of these classes have extensive documentation (apart from WP_Error). Otto has a great tutorial on WP_Filesystem which I recommend you read get an understand of how to instantiate it. I will make a tutorial soon on how to use WP_Filesystem is correlation with other WordPress classes so you too can learn how to make applications like this one. 🙂
Questions? Comments? I’d love to have them! Please post any bugs you find or any questions that may arise when using this class because I would love to work them out. I believe this class has some great potential within the WordPress community, so please make sure you let everyone know about it!
Thomas