Skip to content

Instantly share code, notes, and snippets.

@igorbenic
Last active December 18, 2017 12:38
Show Gist options
  • Select an option

  • Save igorbenic/9f722bfcd77022d1f7a24422626f68b0 to your computer and use it in GitHub Desktop.

Select an option

Save igorbenic/9f722bfcd77022d1f7a24422626f68b0 to your computer and use it in GitHub Desktop.
How to enable WordPress Extensions in your Plugin | https://www.ibenic.com/wordpress-extensions-plugin
<?php
/**
* Abstract Extension Class from which all others should be done
*/
if( ! defined( 'ABSPATH' ) ) {
return;
}
abstract class My_Plugin_Extension {
/**
* Extension ID
* @var string
*/
public $id = '';
/**
* Active Indicator
* @var boolean
*/
public $active = false;
/**
* Integration Image
* @var string
*/
public $image = '';
/**
* Integration Title
* @var string
*/
public $title = '';
/**
* Integration Description
* @var string
*/
public $desc = '';
/**
* Load method used to create hooks to extend or apply new features
* This method will be called only on active extensions
*/
public function load() {}
/**
* Buttons to be shown on the Extensions screen
*
* @param array $integrations Array of active integrations.
* @return void
*/
public function buttons( $integrations ) {
if( ! isset( $integrations[ $this->id ] ) ) {
?>
<button type="button" data-integration="<?php echo $this->id; ?>" class="button button-primary button-extension-activate"><?php _e( 'Activate', 'givasap' ); ?></button>
<?php
} else {
?>
<button type="button" data-integration="<?php echo $this->id; ?>" class="button button-default button-extension-deactivate"><?php _e( 'Deactivate', 'givasap' ); ?></button>
<?php
}
?>
<?php
}
}
<?php
add_action( 'wp_ajax_myplugin_activate_extension', 'myplugin_activate_extension_ajax' );
/**
* Activating the Extension through AJAX
* @return void
*/
function myplugin_activate_extension_ajax() {
// Check if there is a nonce and if it is, verify it. Otherwise throw an error
if( ! isset( $_POST['nonce'] )
|| ! wp_verify_nonce( $_POST['nonce'], 'myplugin-nonce' ) ) {
wp_send_json_error( array( 'message' => __( 'Something went wrong!', 'mytextdomain' ) ) );
die();
}
// If we don't have an extension id, don't process any further.
if( ! isset( $_POST['extension'] ) ) {
wp_send_json_error( array( 'message' => __( 'No Integration Sent', 'mytextdomain' ) ) );
die();
}
// The extension to activate
$extension = $_POST['extension'];
$active_extensions = get_active_extensions();
// If that extension is already active, don't process it further.
// If the extension is not active yet, let's try to activate it.
if( ! isset( $active_extensions[ $extension ] ) ) {
// Let's get all the registered extensions.
$extensions = get_extensions();
// Check if we have that extensions registered.
if( isset( $extensions[ $extension ] ) ) {
// Put it in the active extensions array
$active_extensions[ $extension ] = $extensions[ $extension ];
// Trigger an action so some plugins can also process some data here.
do_action( 'my_plugin' . $extension . '_extension_activated' );
// Update the active extensions.
update_option( 'my_plugin_active_extensions', $active_extensions );
wp_send_json_success( array( 'message' => __( 'Activated', 'mytextdomain' ) ) );
die();
}
} else {
// Our extension is already active.
wp_send_json_success( array( 'message' => __( 'Already Activated', 'mytextdomain' ) ) );
die();
}
// Extension might not be registered.
wp_send_json_error( array( 'message' => __( 'Nothing Happened', 'mytextdomain' ) ) );
die();
}
<?php
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_enqueue_scripts' );
/**
* Enqueue Admin Scripts
*/
function my_plugin_admin_enqueue_scripts( $hook_suffix ) {
$hook_scripts = false;
// var_dump the hook suffix so you find your own hook suffix here
// Uncomment below to find the suffix
// var_dump( $hook_suffix ); die();
if( 'page_page_myplugin_extensions' == $hook_suffix ) {
$hook_scripts = true;
}
if ( $hook_scripts ) {
// Be sure to change the URL to the script where you will have it.
wp_register_script( 'myplugin-admin-js', YOUR_PLUGIN_URL_TO_JS . '/myplugin-admin.js', array( 'jquery' ) );
// Localizing our script so we have a global
// Javascript variable myplugin to access the values such as nonce.
wp_localize_script(
'myplugin-admin-js',
'myplugin',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'myplugin-nonce' ),
'text' => array(
'activate' => __( 'Activate', 'mytextdomain' ),
'deactivate' => __( 'Deactivate', 'mytextdomain' ),
)
));
wp_enqueue_script( 'myplugin-admin-js' );
}
}
<?php
add_action( 'wp_ajax_myplugin_deactivate_extension', 'myplugin_deactivate_extension_ajax' );
/**
* Deactivating the Integration through AJAX
* @return void
*/
function myplugin_deactivate_extension_ajax() {
// Check if there is a nonce and if it is, verify it. Otherwise throw an error
if( ! isset( $_POST['nonce'] )
|| ! wp_verify_nonce( $_POST['nonce'], 'myplugin-nonce' ) ) {
wp_send_json_error( array( 'message' => __( 'Something went wrong!', 'mytextdomain' ) ) );
die();
}
// If we don't have an extension id, don't process any further.
if( ! isset( $_POST['extension'] ) ) {
wp_send_json_error( array( 'message' => __( 'No Integration Sent', 'mytextdomain' ) ) );
die();
}
// The extension to activate
$extension = $_POST['extension'];
$active_extensions = get_active_extensions();
// If that extension is already deactived, don't process it further.
// If the extension is active, let's try to deactivate it.
if( isset( $active_extensions[ $extension ] ) ) {
// Remove the extension from the active extensions.
unset( $active_extensions[ $extension ] );
do_action( 'my_plugin' . $extension . '_extension_activated' );
// Update the active extensions.
update_option( 'my_plugin_active_extensions', $active_extensions );
wp_send_json_success( array( 'message' => __( 'Deactivated', 'mytextdomain' ) ) );
die();
} else {
wp_send_json_error( array( 'message' => __( 'Not Activated', 'mytextdomain' ) ) );
die();
}
wp_send_json_error( array( 'message' => __( 'Nothing Happened', 'mytextdomain' ) ) );
die();
}
<?php
/**
* Plugin Name: Example Extension
* Descriptipn: This can be passed as a plugin or inside the main plugin itself.
*/
if( ! defined( 'ABSPATH' ) ) {
return;
}
// Check if the abstract class exists. If not, don't do anything.
// You can define this class after a hook such as plugins_loaded to be sure.
if( ! class_exists( 'My_Plugin_Extension' ) ) { return; }
class My_Plugin_MailChimp extends My_Plugin_Extension {
public function __construct() {
$this->id = 'mailchimp';
$this->image = URL_TO_THE_IMAGE;
$this->title = __( 'MailChimp', 'mytextdomain' );
$this->desc = __( 'MailChimp Integration for My Plugin', 'mytextdomain' );
}
/**
* Load method used to create hooks to extend or apply new features
* This method will be called only on active extensions
*/
public function load() {
add_action( 'user_register', array( $this, 'add_user_to_mailchimp' ) );
}
public function add_user_to_mailchimp( $user_id ) {
// Code to get the user email and subscribe it to Mailchimp.
}
}
add_filter( 'my_plugin_extensions', 'add_mailchimp_extension' );
/**
* Add mailchimp extension by passing the id and the name of the class.
*
* @param array $extensions
* @return array
*/
function add_mailchimp_extension( $extensions ) {
$extensions['mailchimp'] = 'My_Plugin_MailChimp';
return $extensions;
}
<?php
/**
* Get all activated extensions
*/
function get_active_extensions() {
return get_option( 'my_plugin_active_extensions', array() );
}
<?php
/**
* Get all the registered extensions through a filter
*/
function get_extensions() {
return apply_filters( 'my_plugin_extensions', array() );
}
<?php
/**
* This hook can be on 'init' also all if you have a custom one like this
*/
add_action( 'my_plugin_loaded', 'my_plugin_loading_extensions' );
function my_plugin_loading_extensions() {
$active_extensions = get_active_extensions();
if( $active_extensions ) {
foreach( $active_extensions as $slug => $extension ) {
if( ! class_exists( $extension ) ) {
continue;
}
$extension = new $extension();
$extension->load();
}
}
}
(function($){
$( document ).on( 'click', '.button-extension-activate', function( e ){
e.preventDefault();
// Get the current extension ID
var extension = $(this).attr('data-integration'),
$this = $(this);
if( extension ) {
// Process AJAX
$.ajax({
url: myplugin.ajax_url,
dataType: 'json',
type: 'POST',
data: { action: 'myplugin_activate_extension', extension: extension, nonce: myplugin.nonce },
success: function(resp) {
if( resp.success ) {
// On success, add the deactivate class and remove the activate class.
// Also remove the primary class so we have a gray button and not a blue one.
$this.addClass('button-integration-deactivate')
.addClass('button-default')
.removeClass('button-integration-activate')
.removeClass('button-primary')
.html( myplugin.text.deactivate );
}
}
});
}
});
})(jQuery);
(function($){
// ...
$( document ).on( 'click', '.button-extension-deactivate', function( e ){
e.preventDefault();
var extension = $(this).attr('data-integration'),
$this = $(this);
if( extension ) {
$.ajax({
url: myplugin.ajax_url,
dataType: 'json',
type: 'POST',
data: { action: 'myplugin_deactivate_extension', extension: extension, nonce: myplugin.nonce },
success: function(resp) {
if( resp.success ) {
$this.removeClass('button-integration-deactivate')
.removeClass('button-default')
.addClass('button-integration-activate')
.addClass('button-primary')
.html( myplugin.text.activate );
}
}
});
}
});
})(jQuery);
<?php
add_action( 'admin_menu', 'my_plugin_add_extensions_submenu' );
/**
* Add a submenu
* Assuming we have a parent menu such as a custom post type
* Otherwise add it as a menu or under some other parent menu
*/
function my_plugin_add_extensions_submenu() {
add_submenu_page(
'edit.php?post_type=page', // Put your cpt slug if you have one
__( 'Extensions', 'mytextdomain' ),
__( 'Extensions', 'mytextdomain' ),
'manage_options',
'myplugin_extensions',
'my_plugin_extensions_html' );
}
<?php
/**
* Admin Screen for extensions
*/
function my_plugin_extensions_html() {
// Get all extensions
$all_extensions = get_extensions();
// Get active extensions
$active_extensions = get_active_extensions();
?>
<div class="wrap">
<h1><?php echo get_admin_page_title(); ?></h1>
<p><?php _e( 'All My Plugin Extensions. Choose which to use and activate them.', 'mytextdomain' ); ?></p>
<div class="wp-list-table widefat plugin-install">
<div id="the-list">
<?php
if( $all_extensions ) {
foreach ( $all_extensions as $slug => $class ) {
if( ! class_exists( $class ) ) {
continue;
}
// Instantiate each extension
$extension_object = new $class();
// We will use this object to get the title, description and image of the extension.
?>
<div class="plugin-card plugin-card-<?php echo $slug; ?>">
<div class="plugin-card-top">
<div class="name column-name">
<h3>
<?php echo $extension_object->title; ?>
<img src="<?php echo $extension_object->image; ?>" class="plugin-icon" alt="">
</h3>
</div>
<div class="desc column-description">
<p><?php echo $extension_object->desc; ?></p>
</div>
</div>
<div class="plugin-card-bottom">
<?php
// Use the buttons from our Abstract class to create the buttons
// Can be overwritten by each integration if needed.
$extension_object->buttons( $active_extensions );
?>
</div>
</div>
<?php
}
}
?>
</div>
</div>
</div>
<?php
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment