Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

There're the functions get_theme_data(); & get_plugin_data(); - which both use get_file_data(); that needs a specific file as $input.

I got a set of classes that may be used by a plugin or a theme, without a specific location. Everything works, but I don't know how i would determine what the main plugin or theme file is - I mean the one containing the comment header that holds the information (Version, Author, etc.) about the Theme/Plugin.

share|improve this question
add comment

3 Answers

You can get theme's main file using following:

$theme_info_file = trailingslashit( get_template_directory() ) . 'style.css';

To get the plugin's main file you need to know the plugin name. And then you can use following function:

function get_plugin_file( $plugin_name ) {
    require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
    $plugins = get_plugins();
    foreach( $plugins as $plugin_file => $plugin_info ) {
        if ( $plugin_info['Name'] == $plugin_name ) return $plugin_file;
    }
    return null;
}

For example to get the plugin main file for Akismet.

$akismet_plugin_file =  trailingslashit( WP_PLUGIN_DIR ) . get_plugin_file( 'Akismet' );
share|improve this answer
add comment
up vote 2 down vote accepted

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:

  1. if it's a plugin, mu-plugin or a theme
  2. and how deeply nested your container/root theme or plugin folder is.

Notes:

  1. Works for mu-plugins too.
  2. Might not work if an additional theme directory was registered later (thanks to @toscho for the hint).
  3. Performance test for a theme shows 0.0042 sec. loading time on 1.000 runs.
  4. 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
share|improve this answer
add comment

In a recent project I did, I used the following to get the main plugin file & data of my plugin from another file within my plugin, without having to hardcode anything:

get_plugins( '/' . explode( '/', plugin_basename( __FILE__ ) )[0] );

This will return the following:

array (size=1)
  'main_plugin_file.php' => 
    array (size=11)
      'Name' => string 'Plugin Name' (length=11)
      'PluginURI' => string 'http://wordpress.org/plugins/plugin-folder/' (length=41)
      'Version' => string '1.0' (length=3)
      'Description' => string 'BlaBlaBla Something awesome.' (length=148)
      'Author' => string 'Max GJ Panas' (length=12)
      'AuthorURI' => string 'http://maxpanas.com' (length=19)
      'TextDomain' => string 'plugin-name' (length=11)
      'DomainPath' => string '/languages' (length=10)
      'Network' => boolean false
      'Title' => string 'Plugin Name' (length=11)
      'AuthorName' => string 'Max GJ Panas' (length=12)

You can use this in whichever file within your plugin and it should work just fine and you shouldn't need to worry about any of the files being renamed, paths changed, etc.

To get the "path to main plugin file with plugin data" used by various functions such as is_plugin_active() and is_plugin_active_for_network(), from a file that is not the the main plugin file, use the following code:

 $plugin_dir  = explode( '/', plugin_basename( __FILE__ ) )[0];
 $plugin_file = array_keys( get_plugins( "/$plugin_dir" ) )[0];

 if ( is_plugin_active_for_network( "$plugin_dir/$plugin_file" ) ) // for example.
   // do stuff...
share|improve this answer
    
As the question is 2 1/2 years old it's IIRC ... the point was to write something that will figure out by itself if it is in (a) a plugin (b) a mu-plugin (c) a theme and then return which type it is and the main file. My solution above is far from perfect, but I absolutely don't want to think about the idea behind that again :) +1 for your answer anyway. –  kaiser Nov 27 '13 at 0:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.