How do get the comment header data of a theme OR plugin...
... that holds a specific class.
The following shows how you can drop a class inside any plugin or theme and still be able to get any theme or plugin data from the comment header. This is useful for updating settings/db-options for example.
You don't know:
- if it's a plugin, mu-plugin or a theme
- and how deeply nested your container/root theme or plugin folder is.
Notes:
- Works for mu-plugins too.
- Might not work if an additional theme directory was registered later (thanks to @toscho for the hint).
- Performance test for a theme shows 0.0042 sec. loading time on 1.000 runs.
- The following functions are meant to reside in a class.
/**
* Plugin root
* @return Full Path to plugin folder
*/
public function set_root_path()
{
$_path = trailingslashit( str_replace( basename( __FILE__ ), "", plugin_basename( __FILE__ ) ) );
// Allow overriding the location
$_path = apply_filters( __CLASS__.'_root', $_path );
return $this->_path = $_path;
}
/**
* Gets the data of the base 'theme' / 'plugin' / 'wpmuplugin'
* Performance: average loading time on a local (not vanilla) install for 1.000 runs: 0.0042 sec.
*
* @param (mixed) $value
* @return (array) $value | Theme/Plugin comment header data OR false on failure | default: 'Version'
*/
public function get_data( $value = 'Version' )
{
// Class basename - String to Array
$_path_data = explode( '/', $this->_path );
// Get rid of the last element, as it's only a trailing slash
array_pop( $_path_data );
// reverse for faster processing
krsort( $_path_data );
// Themes basename
$theme_roots = get_theme_roots();
// In case some used register_theme_directory(); before
// Might not work if an additional themes directory will be registered later
// Thanks to @Thomas Scholz <http://toscho.de> for the hint
if ( is_array( $theme_roots ) )
{
foreach ( $_path_data as $_path_part )
{
foreach( $theme_roots as $root )
{
if ( in_array( $root, $_path_data ) )
$_theme_root = $root;
}
}
}
else
{
// Get rid of the leading slash
$_theme_root = str_replace( '/', '', $theme_roots );
}
// Plugins basename
$_plugin_root = basename( WP_PLUGIN_DIR );
# >>>> get file & load data
$base_file = '';
// Themes
if ( in_array( $_theme_root, $_path_data ) )
{
foreach ( search_theme_directories() as $folder => $data )
{
foreach ( $_path_data as $_path_part )
{
if ( $_path_part == $folder )
$base_file = trailingslashit( $data['theme_root'] ).$data['theme_file'];
}
}
$file_data = get_theme_data( $base_file );
}
// Plugins
elseif( in_array( $_plugin_root, $_path_data ) )
{
$plugins = get_plugins();
foreach ( $plugins as $plugin_file => $plugin_info )
{
$data = explode( '/', $plugin_file );
$file = $data[1];
foreach ( $_path_data as $_path_part )
{
if ( $_path_part !== $file )
$base_file = WP_CONTENT_DIR.$_type.'/'.$data[0].'/'.$data[1];
}
}
$file_data = get_plugin_data( $base_file );
}
// WPMU Plugins
else
{
// MU plugins basename - compatible for older MU too
// Thanks (again) to @Thomas Scholz <http://toscho.de> for the hint that mu plugins really exists
$mu_plugin_dir = ! version_compare( $GLOBALS['wp_version'], '3.0.0', '>=' ) ? MUPLUGINDIR : WPMU_PLUGIN_DIR;
$_mu_plugin_root = basename( $mu_plugin_dir );
if ( ! in_array( $_mu_plugin_root, $_path_data ) )
return false;
$mu_plugins = get_mu_plugins();
foreach ( $mu_plugins as $mu_plugin_file => $mu_plugin_info )
{
$data = explode( '/', $mu_plugin_file );
$file = $data[1];
foreach ( $_path_data as $_path_part )
{
if ( $_path_part !== $file )
$base_file = WP_CONTENT_DIR.$_type.'/'.$data[0].'/'.$data[1];
}
}
$file_data = get_plugin_data( $base_file );
}
# <<<< get file & load data
// return
if ( ! empty ( $file_data ) )
return $file_data[ $value ];
// return false to determine that we couldn't load the comment header data
return false;
}
Usage Example:
echo $this->get_data( 'Author' ); // The Plugin or Theme Author
echo $this->get_data( 'Version' ); // The Plugin or Theme Version
echo $this->get_data( 'Name' ); // The Plugin or Theme Name