Skip to content

OOP, extended API, example plugin #6

Merged
merged 4 commits into from Jun 28, 2012
View
41 example_plugin/register_addt_plugins_dir.php
@@ -0,0 +1,41 @@
+<?php
+! defined( 'ABSPATH' ) AND exit();
+/*
+Plugin Name: Additional Plugin Directories: Example Plugin
+Plugin URI: http://github.com/chrisguitarguy
+Description: Example Plugin to show how to register additional plugin directories
+Version: 0.1
+Author: Franz Josef Kaiser
+Author URI: http://unserkaiser.com
+License: MIT
+*/
+
+
+/**
+ * Registers a new plugin directory
+ *
+ * @example
+ * $args Array (Valid args for `root`) 'content', 'plugins', 'muplugins', 'root'
+ * The new directories must be subdirectories of the following WP file system constants:
+ * 'content': (default) WP_CONTENT_DIR
+ * 'plugins': WP_PLUGIN_DIR
+ * 'muplugins': WPMU_PLUGIN_DIR
+ * 'root': one level below WP_CONTENT_DIR
+ *
+ * @return void
+ */
+function cd_apd_register_additional_plugin_directories()
+{
+ // Better abort - if we don't do this, we'll create an error on deactivation of the main plugin.
+ if ( ! function_exists( 'register_plugin_directory' ) )
+ return;
+
+ // Call the public API function once for every directory you want to add.
+ register_plugin_directory( array(
+ 'dir' => 'example_plugin_directory'
+ ,'label' => 'Example Label for the list table'
+ ,'root' => 'plugins'
+ ) );
+}
+// Needs to be added on the `plugins_loaded` hook with a priority of `0`.
+add_action( 'plugins_loaded', 'cd_apd_register_additional_plugin_directories', 0 );
View
183 inc/admin.php
@@ -1,57 +1,116 @@
<?php
-! defined( 'ABSPATH' ) && exit();
+! defined( 'ABSPATH' ) AND exit();
-class CD_APD_Admin
+
+if ( ! class_exists( 'CD_APD_Admin' ) )
+{
+ add_action( 'plugins_loaded', array( 'CD_APD_Admin', 'instance' ) );
@franz-josef-kaiser
Collaborator

Hooking the main class into plugins_loaded on priority 10. This will allow people better control via hooks. It also makes sure, the new static $instance only runs once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+/**
+ * Admin/Factory
+ *
+ * @author Christopher Davis, Franz Josef Kaiser
+ * @license GPL
+ * @copyright © Christopher Davis, Franz Josef Kaiser 2011-2012
+ *
+ * @package WordPress
+ * @subpackage Additional Plugin Directories: Admin/Factory
+ */
+class CD_APD_Admin extends CD_APD_Core
{
/**
+ * Instance
+ *
+ * @since 0.3
+ * @access protected
+ * @var object
+ */
+ protected static $instance;
+
+
+ /**
* The container for all of our custom plugins
+ *
+ * @since 0.1
+ * @access protected
+ * @var array
*/
protected $plugins = array();
+
/**
* What custom actions are we allowed to handle here?
+ *
+ * @since 0.1
+ * @access protected
+ * @var array
*/
protected $actions = array();
+
/**
* The original count of the plugins
+ *
+ * @since 0.1
+ * @access protected
+ * @var int
*/
protected $all_count = 0;
+
+ /**
+ * Creates a new static instance
+ *
+ * @since 0.3
+ * @static
+ * @return void
+ */
+ public static function instance()
+ {
+ null === self :: $instance AND self :: $instance = new self;
+ return self :: $instance;
+ }
+
+
/**
* constructor
*
- * @since 0.1
+ * @since 0.1
+ * @return void
*/
public function __construct()
{
- add_action( 'load-plugins.php', array( $this, 'init' ) );
add_action( 'plugins_loaded', array( $this, 'setup_actions' ), 1 );
+ add_action( 'load-plugins.php', array( $this, 'init' ) );
}
/**
* Sets up which actions we can handle with this plugin. We'll use this
- * to catch activations and deactivations as the normal way won't work
+ * to catch activations and deactivations as the normal way won't work.
+ * Has the filter 'custom_plugin_actions' to allow extensions.
*
- * @since 0.1
+ * @since 0.1
+ * @return void
*/
public function setup_actions()
{
- $tmp = array(
- 'custom_activate',
- 'custom_deactivate'
+ $this->actions = apply_filters(
+ 'custom_plugin_actions',
+ array(
+ 'custom_activate',
+ 'custom_deactivate'
+ )
);
- $this->actions = apply_filters( 'custom_plugin_actions', $tmp );
}
/**
- * Makes the magic happen. Loads all the other hooks to modify the
- * plugin list table
+ * Makes the magic happen. Loads all the other hooks to modify the plugin list table
*
- * @since 0.1
+ * @since 0.1
+ * @return void
*/
public function init()
{
@@ -81,7 +140,9 @@ public function init()
/**
* Adds our custom plugin directories to the list of plugin types
*
- * @since 0.1
+ * @since 0.1
+ * @param array $views
+ * @return array $views
*/
public function views( $views )
{
@@ -94,15 +155,17 @@ public function views( $views )
// Add our directories to the action links
foreach ( $wp_plugin_directories as $key => $info )
{
- if ( ! count( $this->plugins[$key] ) )
+ $count = count( $this->plugins[ $key ] );
+
+ if ( ! $count )
continue;
$views[ $key ] = sprintf(
'<a href="%s"%s>%s <span class="count">(%d)</span></a>',
add_query_arg( 'plugin_status', $key, 'plugins.php' ),
$this->get_plugin_status() == $key ? ' class="current" ' : '',
esc_html( $info['label'] ),
- count( $this->plugins[ $key ] )
+ $count
);
}
@@ -112,6 +175,10 @@ public function views( $views )
/**
* Unset inactive plugin link as it doesn't really work for this view
+ *
+ * @since 0.1
+ * @param array $views
+ * @return array $views
*/
public function views_again( $views )
{
@@ -124,10 +191,15 @@ public function views_again( $views )
/**
* Filters the plugins list to include all the plugins in our custom directory
+ *
+ * @since 0.1
+ * @param array $plugins
+ * @return array $plugins
*/
public function filter_plugins( $plugins )
{
- if ( $key = $this->get_plugin_status() )
+ $key = $this->get_plugin_status();
+ if ( $key )
{
$this->all_count = count( $plugins );
$plugins = $this->plugins[ $key] ;
@@ -139,23 +211,32 @@ public function filter_plugins( $plugins )
/**
* Correct some action links so we can actually "activate" plugins
+ *
+ * @since 0.1
+ * @param array $links
+ * @param string $plugin_file
+ * @return array $links
*/
public function action_links( $links, $plugin_file )
{
$context = $this->get_plugin_status();
+ $active = get_option( "active_plugins_{$context}", array() );
+
// let's just start over
$links = array();
- $links['activate'] = sprintf(
- '<a href="%s" title="Activate this plugin">%s</a>',
- wp_nonce_url(
- "plugins.php?action=custom_activate&amp;plugin={$plugin_file}&amp;plugin_status=".esc_attr( $context ),
- "custom_activate-{$plugin_file}"
- ),
- __( 'Activate' )
- );
+ if ( ! in_array( $plugin_file, $active ) )
+ {
+ $links['activate'] = sprintf(
+ '<a href="%s" title="Activate this plugin">%s</a>',
+ wp_nonce_url(
+ "plugins.php?action=custom_activate&amp;plugin={$plugin_file}&amp;plugin_status=".esc_attr( $context ),
+ "custom_activate-{$plugin_file}"
+ ),
+ __( 'Activate' )
+ );
+ }
- $active = get_option( "active_plugins_{$context}", array() );
if ( in_array( $plugin_file, $active ) )
{
$links['deactivate'] = sprintf(
@@ -175,14 +256,18 @@ public function action_links( $links, $plugin_file )
/**
* Enqueues on JS file for fun hacks
*
- * @since 0.1
- * @uses wp_enqueue_script
+ * @since 0.1
+ * @uses wp_enqueue_script()
+ * @return void
*/
- public function scripts()
+ public function scripts( $screen )
{
+ if ( 'plugins.php' !== $screen )
+ return;
+
wp_enqueue_script(
'cd-apd-js',
- CD_APD_URL . 'js/apd.js',
+ CD_APD_URL.'js/apd.js',
array( 'jquery' ),
null
);
@@ -199,8 +284,9 @@ public function scripts()
/**
* Fetch all the custom plugins we have!
*
- * @since 0.1
- * @uses cd_adp_get_plugins To fetch all the custom plugins
+ * @since 0.1
+ * @uses get_plugins_from_cache() To fetch all the custom plugins
+ * @return void
*/
public function get_plugins()
{
@@ -210,7 +296,7 @@ public function get_plugins()
foreach ( array_keys( $wp_plugin_directories ) as $key )
{
- $this->plugins[ $key ] = cd_apd_get_plugins( $key );
+ $this->plugins[ $key ] = $this->get_plugins_from_cache( $key );
}
}
@@ -219,7 +305,8 @@ public function get_plugins()
* Handle activations and deactivations as the standard way will
* fail with "plugin file does not exist
*
- * @since 0.1
+ * @since 0.1
+ * @return void
*/
public function handle_actions()
{
@@ -240,11 +327,11 @@ public function handle_actions()
{
case 'custom_activate':
if ( ! current_user_can('activate_plugins') )
- wp_die( __('You do not have sufficient permissions to manage plugins for this site.') );
+ wp_die( __( 'You do not have sufficient permissions to manage plugins for this site.' ) );
check_admin_referer( "custom_activate-{$plugin}" );
- $result = cd_apd_activate_plugin( $plugin, $context );
+ $result = $this->activate_plugin( $plugin, $context );
if ( is_wp_error( $result ) )
{
if ( 'unexpected_output' == $result->get_error_code() )
@@ -278,15 +365,21 @@ public function handle_actions()
wp_die( __( 'You do not have sufficient permissions to deactivate plugins for this site.' ) );
check_admin_referer( "custom_deactivate-{$plugin}" );
- cd_apd_deactivate_plugins( $plugin, $context );
+
+ $this->deactivate_plugins( $plugin, $context );
+
if ( headers_sent() )
+ {
printf(
"<meta http-equiv='refresh' content='%s' />",
esc_attr( "0;url=plugins.php?deactivate=true&plugin_status={$status}&paged={$page}&s={$s}" )
);
+ }
else
- wp_redirect( self_admin_url("plugins.php?deactivate=true&plugin_status={$context}") );
- exit();
+ {
+ wp_redirect( self_admin_url( "plugins.php?deactivate=true&plugin_status={$context}" ) );
+ exit();
+ }
break;
default:
@@ -297,11 +390,11 @@ public function handle_actions()
/**
- * Utility function to get the current `plugin_status` key returns
- * false if our key isn't in the the custom directories
+ * Utility function to get the current `plugin_status`.
+ * The key returns FALSE if our key isn't in the the custom directories
*
- * @since 0.1
- * @return bool|string False on failure, the `$wp_plugin_directories` key on success
+ * @since 0.1
+ * @return bool|string $rv False on failure, the `$wp_plugin_directories` key on success
*/
public function get_plugin_status()
{
@@ -319,6 +412,6 @@ public function get_plugin_status()
return $rv;
}
-} // end class
+} // END Class CD_APD_Admin
-new CD_APD_Admin();
+} // endif;
View
134 inc/api.php
@@ -0,0 +1,134 @@
+<?php
+! defined( 'ABSPATH' ) AND exit();
+
+
+
+/**
+ * The central API
+ *
+ * @author Christopher Davis, Franz Josef Kaiser
+ * @license GPL
+ * @copyright © Christopher Davis, Franz Josef Kaiser 2011-2012
+ *
+ * @since 0.3
+ * @package Additional Plugin directories
+ * @subpackage The central API
+ */
+
+
+/**
+ * Registers a new plugin directory.
+ *
+ * @since 0.1
+ * @uses _get_new_plugin_directory_root()
+ * @param array $args An Array of arguments: 'dir' = Name of the directory, 'label' = What you read above the list table, 'case' = Where the dir resides.
+ * @param string $deprecated_dir (deprecated arg) The new plugin directory. Either a full path or a folder name within wp-content.
+ * @param string $deprecated_label (deprecated arg) The nice name of the plugin directory. Presented in the list table.
+ * @return bool TRUE on success, FALSE in case the $key/$label is already in use.
+ */
+function register_plugin_directory( $args, $deprecated_dir = '', $deprecated_label = '' )
+{
+ // The call was too late (or too early in case of a MU-Plugin)
+ if ( 'plugins_loaded' !== current_filter() )
@franz-josef-kaiser
Collaborator

Make sure we run stuff on the right filter. If not, we're adding a note for the user that she/he should fix stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ {
+ _doing_it_wrong(
+ __FUNCTION__
+ ,__( 'Registering a new plugin directory should be done during the `plugins_loaded` hook on priority `0`.', 'cd_apd_textdomain' )
+ ,'0.1'
+ );
+ }
+
+ // Deprecating single arguments
+ if ( ! is_array( $args ) )
@franz-josef-kaiser
Collaborator

Moving input arguments to an array...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ {
+ $info = debug_backtrace();
+ // The key now gets built from the label: Converted to lowercase alphanumeric string.
+ _deprecated_argument(
+ __FUNCTION__
+ ,'0.3'
+ ,sprintf(
+ __( "%sYou need to specify the arguments &ndash; when registering new plugin directories &ndash; as associative array.%s%s", 'cd_apd_textdomain' )
+ ,'<br /><blockquote><strong>'
+ ,'</strong></blockquote>'
+ ,"The call was from within: <code>{$info[ 0 ]['file']}</code> in the function: <code>{$info[ 1 ]['function']}()</code>.<br />"
+ )
+ );
+
+ // Fix for back compat
+ $args = array(
@franz-josef-kaiser
Collaborator

...and making sure stuff doesn't break and is backwards compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ 'dir' => $deprecated_dir
+ ,'label' => $deprecated_label
+ );
+ }
+
+ // Setup defaults
+ $args = wp_parse_args( $args, array( 'root' => 'content' ) );
+
+ global $wp_plugin_directories;
+
+ empty( $wp_plugin_directories ) AND $wp_plugin_directories = array();
+
+ $new_dir = _get_new_plugin_directory_root( $args['root'] ).$args['dir'];
+
+ if ( ! file_exists( $args['dir'] ) AND file_exists( $new_dir ) )
+ {
+ $args['dir'] = $new_dir;
+ }
+
+ // Build $key from $label
+ $key = strtolower( preg_replace( "/[^a-zA-Z0-9\s]/", "", $args['label'] ) );
+
+ // Return FALSE in case we already got the key
+ if ( isset( $wp_plugin_directories[ $key ] ) )
+ return false;
+
+ // Assign the directory
+ $wp_plugin_directories[ $key ] = array(
+ 'dir' => $args['dir']
+ ,'label' => $args['label']
+ ,'root' => $args['root']
+ );
+
+ return true;
+}
+
+
+/**
+ * Retrieves the root path for the new plugin directory.
+ *
+ * @internal Callback function for register_plugin_directory()
+ *
+ * @since 0.3
+ * @param string $case Valid: 'content', 'plugins', 'muplugins', 'root'.
+ * @return string $root The root path based on the WP filesystem constants.
+ */
+function _get_new_plugin_directory_root( $root )
@franz-josef-kaiser
Collaborator

Now we're supporting all different sorts of locations. The switch makes sure, we can easily add in additional cases. Maybe we should also add an filter?

@chrisguitarguy
Owner
case 'content':
default:
    $root = apply_filters("adp_root_{$root}", WP_CONTENT_DIR);

Probably a good idea. Makes it more flexible.

@franz-josef-kaiser
Collaborator
case 'content' :
    $root = WP_CONTENT_DIR;
    break;

default :
    $root = apply_filters( "adp_root_{$root}", WP_CONTENT_DIR );
    break;

...to move 'content' away from any other behavior. This would allow to add whatever/custom/etc... as arg and then make use of the filter.

@chrisguitarguy
Owner

Sounds good to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+{
+ switch ( $root )
+ {
+ case 'plugins' :
+ $root = WP_PLUGIN_DIR;
+ break;
+
+ case 'muplugins' :
+ $root = WPMU_PLUGIN_DIR;
+ break;
+
+ // Experimental Edge Case:
+ // Assuming that the WP_CONTENT_DIR is a direct child of the root directory
+ // and directory separators are "/" above that.
+ // Maybe needs enchancements later on. Wait for feedback in Issues.
+ case 'root' :
+ $root = explode( DIRECTORY_SEPARATOR, WP_CONTENT_DIR );
+ $root = explode( '/', array_pop( $root ) );
+ $root = array_pop( $root );
+ break;
+
+ case 'content' :
+ default :
+ $root = WP_CONTENT_DIR;
+ break;
+ }
+
+ return trailingslashit( $root );
+}
View
388 inc/core.php
@@ -2,248 +2,280 @@
! defined( 'ABSPATH' ) AND exit();
+
+if ( ! class_exists( 'CD_APD_Core' ) )
+{
+
/**
- * The central API: registers a new plugin directory
+ * Core
*
- * @since 0.1
- * @param $key The plugin directory key. Used internally in the plugin list table and to save options.
- * @param $dir The new plugin directory. Either a full path or a folder name within wp-content.
- * @param $label The nice name of the plugin directory. Presented in the list table
+ * @author Christopher Davis, Franz Josef Kaiser
+ * @license GPL
+ * @copyright © Christopher Davis, Franz Josef Kaiser 2011-2012
+ *
+ * @package WordPress
+ * @subpackage Additional Plugin Directories: Core
*/
-function register_plugin_directory( $key, $dir, $label )
+class CD_APD_Core
{
- global $wp_plugin_directories;
-
- empty( $wp_plugin_directories ) AND $wp_plugin_directories = array();
-
- if ( ! file_exists( $dir ) AND file_exists( trailingslashit( WP_CONTENT_DIR ) . $dir ) )
+ /**
+ *
+ */
+ public function __construct()
{
- $dir = trailingslashit( WP_CONTENT_DIR ) . $dir;
+ add_action( 'plugins_loaded', array( $this, 'load_plugins' ), 99 );
}
- $wp_plugin_directories[ $key ] = array(
- 'label' => $label,
- 'dir' => $dir
- );
-}
-
-add_action( 'plugins_loaded', 'cd_apd_load_more', 99 );
-/**
- * Loads additional plugins from custom directories. To add a directory,
- * you must do so in a plugin (hooked into `plugins_loaded` with a low
- * priority
- */
-function cd_apd_load_more()
-{
- global $wp_plugin_directories;
-
- empty( $wp_plugin_directories ) AND $wp_plugin_directories = array();
- foreach ( array_keys( $wp_plugin_directories ) as $key )
+ /**
+ * Loads additional plugins from custom directories.
+ * To add a directory, you must do so in a plugin (hooked into `plugins_loaded` with a low priority).
+ *
+ * @since 0.1
+ * @return void
+ */
+ public function load_plugins()
{
- $active = get_option( "active_plugins_{$key}", array() );
- foreach( $active as $a )
+ global $wp_plugin_directories;
+
+ empty( $wp_plugin_directories ) AND $wp_plugin_directories = array();
+
+ foreach ( array_keys( $wp_plugin_directories ) as $key )
{
- if ( file_exists( "{$wp_plugin_directories[ $key ]['dir']}/{$a}" ) )
+ $active = get_option( "active_plugins_{$key}", array() );
+ foreach( $active as $a )
{
- include_once( "{$wp_plugin_directories[ $key ]['dir']}/{$a}" );
+ if ( file_exists( "{$wp_plugin_directories[ $key ]['dir']}/{$a}" ) )
+ {
+ include_once( "{$wp_plugin_directories[ $key ]['dir']}/{$a}" );
+ }
}
}
}
-}
-/**
- * Get the valid plugins from the custom directory
- *
- * @since 0.1
- * @param $dir_key The `key` of our custom plugin directory
- * @return array A list of the plugins
- */
-function cd_apd_get_plugins( $dir_key )
-{
- global $wp_plugin_directories;
+ /**
+ * Get the valid plugins from the custom directory
+ *
+ * @since 0.1
+ * @param $dir_key The `key` of our custom plugin directory
+ * @return array A list of the plugins
+ */
+ public function get_plugins_from_cache( $dir_key )
+ {
+ global $wp_plugin_directories;
- // invalid dir key? bail
- if ( ! isset( $wp_plugin_directories[ $dir_key ] ) )
- return array();
+ // invalid dir key? bail
+ if ( ! isset( $wp_plugin_directories[ $dir_key ] ) )
+ return array();
- $plugin_root = $wp_plugin_directories[ $dir_key ]['dir'];
+ $plugin_root = $wp_plugin_directories[ $dir_key ]['dir'];
- if ( ! $cache_plugins = wp_cache_get( 'plugins', 'plugins') )
- $cache_plugins = array();
+ if ( ! $cache_plugins = wp_cache_get( 'plugins', 'plugins') )
+ $cache_plugins = array();
- if ( isset( $cache_plugins[ $dir_key ] ) )
- return $cache_plugins[ $dir_key ];
+ if ( isset( $cache_plugins[ $dir_key ] ) )
+ return $cache_plugins[ $dir_key ];
- $wp_plugins = array();
+ $wp_plugins = array();
- $plugins_dir = @ opendir( $plugin_root );
- $plugin_files = array();
- if ( $plugins_dir ) {
- while ( ( $file = readdir( $plugins_dir ) ) !== false ) {
- if ( substr($file, 0, 1) == '.' )
- continue;
- if ( is_dir( "{$plugin_root}/{$file}" ) ) {
- $plugins_subdir = @ opendir( "{$plugin_root}/{$file}" );
- if ( $plugins_subdir ) {
- while ( ( $subfile = readdir( $plugins_subdir ) ) !== false ) {
- if ( substr($subfile, 0, 1) == '.' )
- continue;
- if ( substr($subfile, -4) == '.php' )
- $plugin_files[] = "{$file}/{$subfile}";
+ $plugins_dir = @ opendir( $plugin_root );
+ $plugin_files = array();
+ if ( $plugins_dir )
+ {
+ while ( false !== ( $file = readdir( $plugins_dir ) ) )
+ {
+ if ( '.' === substr( $file, 0, 1 ) )
+ continue;
+
+ if ( is_dir( "{$plugin_root}/{$file}" ) )
+ {
+ $plugins_subdir = @ opendir( "{$plugin_root}/{$file}" );
+ if ( $plugins_subdir )
+ {
+ while ( ( $subfile = readdir( $plugins_subdir ) ) !== false )
+ {
+ if ( '.' === substr( $subfile, 0, 1 ) )
+ continue;
+
+ if ( '.php' === substr( $subfile, -4 ) )
+ $plugin_files[] = "{$file}/{$subfile}";
+ }
+ closedir( $plugins_subdir );
}
- closedir( $plugins_subdir );
}
- } else {
- '.php' === substr( $file, -4 ) AND $plugin_files[] = $file;
+ else
+ {
+ '.php' === substr( $file, -4 ) AND $plugin_files[] = $file;
+ }
}
+ closedir( $plugins_dir );
}
- closedir( $plugins_dir );
- }
- if ( empty( $plugin_files ) )
- return $wp_plugins;
+ if ( empty( $plugin_files ) )
+ return $wp_plugins;
- foreach ( $plugin_files as $plugin_file ) {
- if ( ! is_readable( "{$plugin_root}/{$plugin_file}" ) )
- continue;
+ foreach ( $plugin_files as $plugin_file )
+ {
+ if ( ! is_readable( "{$plugin_root}/{$plugin_file}" ) )
+ continue;
- // Do not apply markup/translate as it'll be cached.
- $plugin_data = get_plugin_data( "{$plugin_root}/{$plugin_file}", false, false );
+ // Do not apply markup/translate as it'll be cached.
+ $plugin_data = get_plugin_data( "{$plugin_root}/{$plugin_file}", false, false );
- if ( empty ( $plugin_data['Name'] ) )
- continue;
+ if ( empty ( $plugin_data['Name'] ) )
+ continue;
- $wp_plugins[ trim( $plugin_file ) ] = $plugin_data;
- }
+ $wp_plugins[ trim( $plugin_file ) ] = $plugin_data;
+ }
- uasort( $wp_plugins, '_sort_uname_callback' );
+ uasort( $wp_plugins, '_sort_uname_callback' );
- $cache_plugins[ $dir_key ] = $wp_plugins;
- wp_cache_set( 'plugins', $cache_plugins, 'plugins' );
+ // Setup cache, if we ain't already got one.
+ // If we got one, we already returned the cached plugins.
+ $cache_plugins[ $dir_key ] = $wp_plugins;
+ wp_cache_set( 'plugins', $cache_plugins, 'plugins' );
- return $wp_plugins;
-}
+ return $wp_plugins;
+ }
-/**
- * Custom plugin activation function.
- */
-function cd_apd_activate_plugin( $plugin, $context, $silent = false )
-{
- $plugin = trim( $plugin );
+ /**
+ * Custom plugin activation function.
+ *
+ * @since 0.1
+ * @return void
+ */
+ public function activate_plugin( $plugin, $context, $silent = false )
+ {
+ $plugin = trim( $plugin );
- $redirect = add_query_arg( 'plugin_status', $context, admin_url( 'plugins.php' ) );
- $redirect = apply_filters( 'custom_plugin_redirect', $redirect );
+ $redirect = add_query_arg( 'plugin_status', $context, admin_url( 'plugins.php' ) );
+ $redirect = apply_filters( 'custom_plugin_redirect', $redirect );
- $current = get_option( "active_plugins_{$context}", array() );
+ $current = get_option( "active_plugins_{$context}", array() );
- $valid = cd_apd_validate_plugin( $plugin, $context );
+ $valid = $this->validate_plugin( $plugin, $context );
- if ( is_wp_error( $valid ) )
- return $valid;
+ if ( is_wp_error( $valid ) )
+ return $valid;
- if ( ! in_array( $plugin, $current ) ) {
- if ( ! empty( $redirect ) )
+ if ( ! in_array( $plugin, $current ) )
{
- // we'll override this later if the plugin can be included without fatal error
- wp_redirect( add_query_arg(
- '_error_nonce'
- ,wp_create_nonce( "plugin-activation-error_{$plugin}" )
- ,$redirect
- ) );
- }
+ if ( ! empty( $redirect ) )
+ {
+ // we'll override this later if the plugin can be included without fatal error
+ wp_redirect( add_query_arg(
+ '_error_nonce'
+ ,wp_create_nonce( "plugin-activation-error_{$plugin}" )
+ ,$redirect
+ ) );
+ }
- ob_start();
- include_once( $valid );
+ ob_start();
+ include_once( $valid );
- if ( ! $silent ) {
- do_action( 'custom_activate_plugin', $plugin, $context );
- do_action( "custom_activate_{$plugin}", $context );
- }
+ if ( ! $silent )
+ {
+ do_action( 'custom_activate_plugin', $plugin, $context );
+ do_action( "custom_activate_{$plugin}", $context );
+ }
- $current[] = $plugin;
- sort( $current );
- update_option( "active_plugins_{$context}", $current );
+ $current[] = $plugin;
+ sort( $current );
+ update_option( "active_plugins_{$context}", $current );
- if ( ! $silent ) {
- do_action( 'custom_activated_plugin', $plugin, $context );
- }
+ if ( ! $silent )
+ {
+ do_action( 'custom_activated_plugin', $plugin, $context );
+ }
- if ( ob_get_length() > 0 ) {
- $output = ob_get_clean();
- return new WP_Error( 'unexpected_output', __( 'The plugin generated unexpected output.' ), $output );
+ if ( ob_get_length() > 0 )
+ {
+ $output = ob_get_clean();
+ return new WP_Error( 'unexpected_output', __( 'The plugin generated unexpected output.' ), $output );
+ }
+ ob_end_clean();
}
- ob_end_clean();
+
+ return true;
}
- return true;
-}
+ /**
+ * Deactivate custom plugins
+ *
+ * @since 0.1
+ * @return void
+ */
+ public function deactivate_plugins( $plugins, $context, $silent = false )
+ {
+ $current = get_option( "active_plugins_{$context}", array() );
-/**
- * Deactivate custom plugins
- */
-function cd_apd_deactivate_plugins( $plugins, $context, $silent = false ) {
- $current = get_option( "active_plugins_{$context}", array() );
+ foreach ( (array) $plugins as $plugin )
+ {
+ $plugin = trim( $plugin );
+ if ( ! in_array( $plugin, $current ) ) continue;
- foreach ( (array) $plugins as $plugin )
- {
- $plugin = trim( $plugin );
- if ( ! in_array( $plugin, $current ) ) continue;
+ if ( ! $silent )
+ do_action( 'custom_deactivate_plugin', $plugin, $context );
- if ( ! $silent )
- do_action( 'custom_deactivate_plugin', $plugin, $context );
+ $key = array_search( $plugin, $current );
+ if ( false !== $key )
+ {
+ array_splice( $current, $key, 1 );
+ }
- $key = array_search( $plugin, $current );
- if ( false !== $key ) {
- array_splice( $current, $key, 1 );
+ if ( ! $silent )
+ {
+ do_action( "custom_deactivate_{$plugin}", $context );
+ do_action( 'custom_deactivated_plugin', $plugin, $context );
+ }
}
- if ( ! $silent ) {
- do_action( "custom_deactivate_{$plugin}", $context );
- do_action( 'custom_deactivated_plugin', $plugin, $context );
- }
+ update_option( "active_plugins_{$context}", $current );
}
- update_option( "active_plugins_{$context}", $current );
-}
-
-/**
- * Checks to see whether the plugin and is valid and can be activated.
- *
- * @uses validate_file To make sure the plugin name is okay.
- * @return WP_Error|string WP_Error object on failure, the plugin to include on success.
- */
-function cd_apd_validate_plugin( $plugin, $context )
-{
- $rv = true;
- if ( validate_file( $plugin ) )
+ /**
+ * Checks to see whether the plugin and is valid and can be activated.
+ *
+ * @uses validate_file To make sure the plugin name is okay.
+ * @param string $plugin
+ * @return array $context
+ * @return WP_Error|string WP_Error object on failure, the plugin to include on success.
+ */
+ public function validate_plugin( $plugin, $context )
{
- $rv = new WP_Error( 'plugin_invalid', __( 'Invalid plugin path.' ) );
- }
+ $rv = true;
+ if ( validate_file( $plugin ) )
+ {
+ $rv = new WP_Error( 'plugin_invalid', __( 'Invalid plugin path.' ) );
+ }
- global $wp_plugin_directories;
+ global $wp_plugin_directories;
- if ( ! isset( $wp_plugin_directories[ $context ] ) )
- {
- $rv = new WP_Error( 'invalid_context', __( 'The context for this plugin does not exist' ) );
- }
+ if ( ! isset( $wp_plugin_directories[ $context ] ) )
+ {
+ $rv = new WP_Error( 'invalid_context', __( 'The context for this plugin does not exist' ) );
+ }
- $dir = $wp_plugin_directories[ $context ]['dir'];
- if ( ! file_exists( "{$dir}/{$plugin}" ) )
- {
- $rv = new WP_Error( 'plugin_not_found', __( 'Plugin file does not exist.' ) );
- }
+ $dir = $wp_plugin_directories[ $context ]['dir'];
+ if ( ! file_exists( "{$dir}/{$plugin}" ) )
+ {
+ $rv = new WP_Error( 'plugin_not_found', __( 'Plugin file does not exist.' ) );
+ }
- $installed_plugins = cd_apd_get_plugins( $context );
- if ( ! isset( $installed_plugins[ $plugin ] ) )
- {
- $rv = new WP_Error( 'no_plugin_header', __('The plugin does not have a valid header.') );
+ $installed_plugins = $this->get_plugins_from_cache( $context );
+ if ( ! isset( $installed_plugins[ $plugin ] ) )
+ {
+ $rv = new WP_Error( 'no_plugin_header', __('The plugin does not have a valid header.') );
+ }
+
+ $rv = "{$dir}/{$plugin}";
+
+ return $rv;
}
+} // END Class CD_APD_Core
- $rv = "{$dir}/{$plugin}";
- return $rv;
-}
+} // endif;
View
22 js/apd.js
@@ -1,10 +1,14 @@
-jQuery(document).ready(function($){
- $('li.all a').removeClass('current').find('span.count').html('(' + cd_apd.count + ')');
- $('.wp-list-table.plugins tr').each(function(){
- var is_active = $(this).find('a.cd-apd-deactivate');
- if(is_active.length) {
- $(this).removeClass('inactive').addClass('active');
- $(this).find('div.plugin-version-author-uri').removeClass('inactive').addClass('active');
+jQuery( document ).ready( function($)
+{
+ // Add the count
+ $( 'li.all a' ).removeClass( 'current' ).find( 'span.count' ).html( '(' + cd_apd.count + ')' );
+ $( '.wp-list-table.plugins tr' ).each( function()
+ {
+ var is_active = $( this ).find( 'a.cd-apd-deactivate' );
+ if ( is_active.length )
+ {
+ $( this ).removeClass( 'inactive' ).addClass( 'active' );
+ $( this ).find( 'div.plugin-version-author-uri' ).removeClass( 'inactive' ).addClass( 'active' );
}
- });
-});
+ } );
+} );
View
20 plugin-dirs.php
@@ -1,22 +1,24 @@
<?php
-! defined( 'ABSPATH' ) && exit();
+! defined( 'ABSPATH' ) AND exit();
/*
-Plugin Name: Additional Plugin Directories
-Plugin URI: http://github.com/chrisguitarugy
-Description: A framework for adding additional plugin directories to WordPress
-Version: 0.1
-Author: Christopher Davis
-Author URI: http://christopherdavis.me
-License: GPL2
+Plugin Name: Additional Plugin Directories
+Plugin URI: http://github.com/chrisguitarguy
+Description: A framework to allow adding additional plugin directories to WordPress
+Version: 0.6
+Author: Christopher Davis
+Contributors: Franz Josef Kaiser, Julien Chaumond
+Author URI: http://christopherdavis.me
+License: GPL2
*/
define( 'CD_APD_PATH', plugin_dir_path( __FILE__ ) );
define( 'CD_APD_URL', plugin_dir_url( __FILE__ ) );
+require_once( CD_APD_PATH.'inc/api.php' );
require_once( CD_APD_PATH.'inc/core.php' );
-if( is_admin() )
+if ( is_admin() )
{
require_once( CD_APD_PATH.'inc/admin.php' );
}
View
21 readme.md
@@ -2,3 +2,24 @@ Add Plugin Directories to WordPress
===================================
A work in progress related to a [WordPress stack exchange question](http://wordpress.stackexchange.com/questions/43262/add-multiple-plugin-directories).
+
+
+EXAMPLE
+
+For an example, take a look at the `example_plugin` folder and the `register_addt_plugins_dir.php` file.
+
+You need to copy this folder to your actual plugins folder and then activate it from within your plugins list. It only works if the main plugin is activated.
+
+*) the one you defined with the `WP_PLUGIN_DIR` or `WPMU_PLUGIN_DIR` in your wp-config.php file - or the default `plugins` folder in your install.
+
+
+CHANGELOG
+
+0.1 Initial version
+0.2 Clean Up & code styling alignment
+0.3 Minor styling fixes
+0.4 Moved to OOP concept
+0.5 Improved API - now supports different plugin locations aside from the `WP_CONTENT_DIR`.
+0.5.1 Minor fix for left over debug code
+0.5.2 JS styling for readability
+0.6 Removed "activate" link when plugin is already active, as suggested by Julien Chaumond in Issue #3
Something went wrong with that request. Please try again.