Ticket #3047 (assigned enhancement)

Opened 2 years ago

Last modified 1 month ago

get_plugininfo()

Reported by: forceagainstsomething Assigned to: jacobsantos (accepted)
Priority: normal Milestone: 2.8
Component: Administration Version: 2.1
Severity: normal Keywords: has-patch needs-testing
Cc:

Description

Attached is a patch to create a new function to be used by plugin developers named get_plugininfo(). Any script that is part of a plugin can call the function to get information about the plugin itself. The function works similar to get_bloginfo().

Example: $url = get_plugininfo('url'); Will return the full URL for the plugin's base directory. $path = get_plugininfo('path'); Will return the full path to the plugin's base directory.

This will save plugin developers from having to define the values themselves.

Attachments

get_plugininfo.diff (3.0 kB) - added by forceagainstsomething on 08/17/06 18:16:57.
get_plugininfo() patch
3047.diff (5.1 kB) - added by westi on 08/20/06 09:39:02.
Alternative implementation of get_plugin_info
get_plugininfo.php (1.4 kB) - added by forceagainstsomething on 08/20/06 21:34:05.
3047a.diff (4.4 kB) - added by westi on 08/21/06 08:30:04.
Replacement patch as descirbed in my comment
3047.r9125.diff (2.9 kB) - added by jacobsantos on 10/12/08 16:57:39.
Updated westi patch for r9125 and new get_plugin_data() function.

Change History

08/17/06 18:16:57 changed by forceagainstsomething

  • attachment get_plugininfo.diff added.

get_plugininfo() patch

08/17/06 18:24:02 changed by forceagainstsomething

  • version set to 2.1.

08/17/06 19:39:24 changed by war59312

Very nice! :)

08/17/06 21:38:19 changed by westi

+1 for the ideas -1 for it's current form

Can we not reuse and extend the code that already exists for loading plugin info and use pre-existing functions like plugin_basename rather than the hacks around with the callstack?

The pre-existing code will already pull in the version info for a plugin and calling something like get_plugininfo(plugin_basename(FILE),$info) isn't hard.

I'll try and code up an example.

It is probably also good to show some examples of how it would be used?

08/17/06 22:04:38 changed by forceagainstsomething

To start with, although already posted to the wp-hackers list, I profiled the current code by running it 1,000 times. That only added 0.137 to WordPress's total running time. Realistically the function would only be called a dozen or so times altogether. So using this function has almost no impact on execution time.

get_plugininfo(plugin_basename(FILE),$info) wouldn't work. Picture a plugin with this structure:

/plugins/myplugin/myplugin.php

/plugins/myplugin/includes/classes/myplugin_class.php

If get_plugininfo(plugin_basename(FILE),$info) was called from the myplugin_class.php script, it would fail.

Sure, it's not the biggest pain in the neck to simply define the values yourself when you're writing the plugin. That being said, any good programmer would move constantly recurring code into a function. The vast majority of the plugins I've looked at are always defining those values, so why not move them into a function?

BTW - You can also find out the blog's URL using some PHP code, but that hasn't stopped the devs from creating the get_bloginfo() function, which can return the URL. These types of functions are for convenience. It makes it easier to work with WP, thus making more people want to write code for WP.

08/19/06 11:08:55 changed by RuddO

This is fantastic. Now my bug #2866 can be a closed case with a truthful resolution (as opposed to a truthy resolution) and my patches applied to WP without any issues.

08/19/06 11:10:51 changed by RuddO

And it's not just convenience. I propose this be a documented plugin API function. Of course, as long as it's fail proof. The submitter should look at but #2866 to see what I mean, and to wade across the politics =)

08/19/06 19:10:59 changed by ryan

debug_backtrace requires PHP 4.3. We support 4.2.

08/19/06 22:10:06 changed by forceagainstsomething

It won't be 4.2 forever. The function could always sit on the back-burner for a few months. Also, and I could be mistaken, but I believe even Debian stable is using PHP 4.3+, which means the vast majority of web hosts should also be using that version or greater (since so many host use Debian stable as their golden rule for updating).

08/20/06 03:04:08 changed by ryan

When we break 4.2 compatibility we hear about it from a suprisingly large number of people. I'd rather not break 4.2 compatibility gratuitously.

08/20/06 09:39:02 changed by westi

  • attachment 3047.diff added.

Alternative implementation of get_plugin_info

08/20/06 09:41:14 changed by westi

  • keywords set to bg|has-patch bg|dev-feedback.
  • owner changed from anonymous to westi.
  • status changed from new to assigned.

I've attached an alternative implementation.

This provides easy access to information about active plugins - all the same info as is loaded for all the plugins in the plugins admin page.

Not fully tested but includes a bug fix and extension of get_plugin_data which is moved to wp-includes/plugins from wp-admin/admin-functions.php to make it available in wp-settings.

08/20/06 17:06:38 changed by forceagainstsomething

For me this new version doesn't work. First, I had to change the get_plugininfo() function to get it to work at all, by adding this at the top:

$plugin_filename = plugin_basename($plugin_filename);

That's if I'm calling the function like: get_plugininfo(FILE, 'path');

Second, this only works in the *base* plugin script, which pretty much defeats the purpose. As I stated in my first reply to you, this function should work for *any* one of the numerous scripts that are part of a plugin.

If I have a plugin with this structure:

/plugins/myplugin/myplugin.php

/plugins/myplugin/includes/classes/myplugin_class.php

Your get_plugininfo() will not work if called from the myplugin_class.php script. Mine does.

Third, if passing the filename to the function is going to be required, then I'd suggest making it the second parameter, like this:

get_plugininfo($info, $plugin_filename)

That way the parameter can by dropped in the future without breaking plugins that are using the function.

08/20/06 20:19:34 changed by westi

Yes my get_plugininfo expects to be called with the plugin_basename version of the plugin file.

How can you provide all of the information in the plugin header by calling it from your included files.

One call to plugin_basename(__FILE__) in the original plugin file being stored in a global variable allows you to call get_plugininfo from any other plugin file.

08/20/06 21:09:14 changed by forceagainstsomething

"One call to plugin_basename(FILE) in the original plugin file being stored in a global variable allows you to call get_plugininfo from any other plugin file."

That's just nasty. :) It's easy to modify your code so that it works the way my function did. I'll get back to you on that change.

08/20/06 21:34:05 changed by forceagainstsomething

  • attachment get_plugininfo.php added.

08/20/06 21:35:32 changed by forceagainstsomething

Okay, attached is a version of your get_plugininfo() function that can be called from any script that is part of a plugin. It's called like this:

get_plugininfo('version', FILE);

That simple.

08/21/06 06:14:01 changed by markjaquith

Can we get it to assume FILE if no 2nd parameter is provided? That'll likely be how most people are using it (within a plugin, accessing information about itself).

08/21/06 06:54:10 changed by masquerade

Also, can we not load all the info on every load. It seems unnecessary, as 99% of plugins won't even use it.

08/21/06 08:29:39 changed by westi

Thank you all for the feedback.

forceagainstsomething: Your version of get_plugininfo falls over as soon as the included file that calls it has the parent plugin in the same folder as another plugin. Then you get back the information about the first plugin that it discovers in that folder rather than the plugin you were included from.

markjaquith: If we assume __FILE__ a the second parameter then __FILE__ will always be wp-includes/plugins.php unfortunately.

masquerade: Yep lazy loading sounds like a good idea - it does break the possibility of doing the kind of stuff forceagainstsomething wanted to do as you can't lazy load when you don't know the filename - but then again I can see a way of knowing the filename of the plugin using the include in his methodology anyway.

I am about to upload a new version of my patch changes are:

  1. Lazy Loading
  2. Change call order to $info, $filename
  3. $filename is now __FILE__ rather than plugin_basename(!__FILE!__);

If you want to get the info from a included file all you need to do is add a simple function like so to your base plugin file:

function my_plugin_getinfo($info) { return get_pluginfo($info, __FILE__);}

Thanks to a sleepy masquerade on irc for that simple oneliner.

08/21/06 08:30:04 changed by westi

  • attachment 3047a.diff added.

Replacement patch as descirbed in my comment

08/21/06 18:47:01 changed by forceagainstsomething

westi: The only situation where an include file for a plugin would be in the directory of another plugin, is when a plugin developer dumps all the scripts for his plugin straight into the /plugins directory. No one should be doing that to begin with.

You're implementation of the function seems pointless to me, since it absolutely must be called from the base plugin script to work. What kind of function *has* to be called only within a certain script? That seems silly and confusing. If it doesn't work as effortlessly as get_bloginfo(), then I don't see any reason to have it at all.

markjaquith: That's what the debug_backtrace() was meant to fix in my original version of the function. It tells a function which script called it. As Ryan pointed out, debug_backtrace() is a PHP 4.3+ function, and WP is meant to support 4.2. That's why I suggested making $filename the second parameter in westi's implementation, so the parameter could be dropped altogether when WP finally supports 4.3+.

08/21/06 20:50:17 changed by westi

"The only situation where an include file for a plugin would be in the directory of another plugin, is when a plugin developer dumps all the scripts for his plugin straight into the /plugins directory. No one should be doing that to begin with."

It is not the include file being in the same directory but the plugin itself.

If the plugin is in the same folder as other plugins with the includes in a child folder your lookup code finds the first (alphabetically I believe) plugin in the folder of plugins and matches that.

My implementation is not pointless - it provides an easy way for a plugin to access the metadata about itself (or another plugin) using the actual plugin file as a reference point.

get_bloginfo can be so effortless because it works for the whole blog it does not need a point of reference - anything that provides the info for a plugin needs a point of reference.

08/21/06 21:07:16 changed by masquerade

Personally, I think that a plugin author should know the name of the file they're working with. get_plugininfo('whatevvv', 'myplugindir/mymainpluginfile.php'); is not hard to type. There's no need for fancy lookups and all that crap from a subplugin file. Or, here's a better idea, in your base plugin file, define myplugin_getinfo($info) { return get_pluginfo($info, __FILE__); }. I see no point in a crappy implementation to work around lazy plugin developers.

08/21/06 21:21:11 changed by forceagainstsomething

"It is not the include file being in the same directory but the plugin itself."

Well you've got me there. Didn't think of that.

"My implementation is not pointless"

I say pointless, because at some point it's not even convenient to use anymore. And convenience is at the heart of this function. Having to call the function from the base plugin script, along with passing FILE to the function, degrades the elegance of the function.

"get_bloginfo can be so effortless because it works for the whole blog it does not need a point of reference - anything that provides the info for a plugin needs a point of reference."

Right, but the goal should be making get_plugininfo() as effetless as get_bloginfo(). Doesn't mean it's going to happen, but that should at least be the goal.

"Personally, I think that a plugin author should know the name of the file they're working with. get_plugininfo('whatevvv', 'myplugindir/mymainpluginfile.php'); is not hard to type."

Not true. I don't hardcode my plugin path, I know others don't either. Most of my plugins start like this:

define('PLUG_BASE', dirname(plugin_basename(FILE)));

define('PLUG_PATH', ABSPATH . 'wp-content/plugins/' . PLUG_BASE);

define('PLUG_URL', get_bloginfo('wpurl') . '/wp-content/plugins/' . PLUG_BASE);

This way the user can rename my plugin's directory, and it still works. If I was to use the method you described, I would still have to define the PLUG_BASE to use whenever I call the get_plugininfo() function. The point of the function is so I don't have to define any more variables. Also I try my damnest not to use global variables or constants inside of classes, so that means I would have to redefine the PLUG_BASE inside every class.

"I see no point in a crappy implementation to work around lazy plugin developers."

You call it lazy, I call it convenient. Like I've said already, you can find out the blog's URL without using get_bloginfo(). So does that make me lazy for using get_bloginfo()? No. It's just convenient.

(follow-up: ↓ 24 ) 04/03/07 16:55:38 changed by _erik_

This is a really great idea! May i suggest to also include a plugins textdomain-name. currently it's set directly in the load_plugin_textdomain()-function and needs to be repeated in every single _e() or ()-string. over and over again... instead of coding around this - the get_plugininfo()-function would come in pretty handy!

a) simplify/shorten the _e() and () functions b) make sure there really is no .mo file - is it in the /plugins/ or in a /pluginsubdir/? c) display localized descriptions (if a plugin brings l10n) in the plugin-panel.

04/03/07 17:15:51 changed by foolswisdom

  • keywords changed from bg|has-patch bg|dev-feedback to has-patch dev-feedback.
  • milestone set to 2.4.

(in reply to: ↑ 22 ; follow-up: ↓ 25 ) 04/03/07 21:27:33 changed by JeremyVisser

Replying to _erik_:

a) simplify/shorten the _e() and __() functions

Whoa, man! How short d'you want to go? They are short as at the moment. I mean, you can't beat _e() or __().

(in reply to: ↑ 24 ) 04/12/07 21:46:51 changed by rob1n

  • milestone changed from 2.4 to 2.3.

Replying to JeremyVisser:

Replying to _erik_:

a) simplify/shorten the _e() and __() functions

Whoa, man! How short d'you want to go? They are short as at the moment. I mean, you can't beat _e() or __().

Yes, if we shrunk them any further, _() is a PHP function and e() could conflict with something else.

05/07/07 09:16:59 changed by _erik_

I mean, you can't beat _e() or ().

ehm... i dont wanna beat _e() or () but if a plugininfo-function exists, it should _also_ tell/know the name of a plugins textdomain. (as i said before) Seems you just got me wrong. When saying 'simplify l10n', i didn't mean the function names. maybe a code example makes it more easy to understand for everybody...

this is the syntax proposed: _e('translate this!', 'wordpress-has-no-idea-what-exact-textdomain-a-plugin-uses'); (even though that it also works without the textdomain - thats the way most people write it down...) it seems convenient to me to let a general get_plugininfo()-function acess this string, too. so one won't have to repeat the name of the textdomain over and over again... currently one will have to add the $path to the call of the textdomain function in a plugin which could be done in the function itself (if it only knew the textdomain/filename for the plugins .mo. it could search where it is stored eg: plugins/ or /plugins/myplugin/ or /plugins/myplugin/subdir/)

most important argument to me would be that this would allow l10n of all plugins uploaded. (eg: descriptions) without actually having the plugin activated or using it

08/23/07 14:03:05 changed by westi

  • keywords changed from has-patch dev-feedback to dev-feedback.
  • milestone changed from 2.3 (trunk) to 2.4 (future).

I'm still not happy with this.

If we do want to provide this functionality then we need to open the discussion about what we should provide.

As feature freeze for 2.3 is near upon us pushing this out to 2.4

Removing has-patch as we will need a new patch for this.

12/09/07 11:01:41 changed by westi

  • keywords changed from dev-feedback to needs-patch.
  • milestone changed from 2.4 to 2.6.

Pushing off into the future for now.

I will look at this later

07/17/08 03:13:31 changed by jacobsantos

  • owner changed from westi to jacobsantos.
  • status changed from assigned to new.

07/17/08 03:13:37 changed by jacobsantos

  • status changed from new to assigned.

10/12/08 16:57:39 changed by jacobsantos

  • attachment 3047.r9125.diff added.

Updated westi patch for r9125 and new get_plugin_data() function.

10/12/08 16:58:01 changed by jacobsantos

  • keywords changed from needs-patch to has-patch needs-testing.

(follow-up: ↓ 33 ) 10/14/08 22:59:09 changed by jacobsantos

Can this still go in? Or does it need to be pushed to 2.8?

(in reply to: ↑ 32 ; follow-up: ↓ 34 ) 10/15/08 20:50:30 changed by westi

  • milestone changed from 2.7 to 2.8.

Replying to jacobsantos:

Can this still go in? Or does it need to be pushed to 2.8?

Thanks for updating my ancient patch.

I think this can push to future for now.

I suspect we may have enought other functionality around now that this isn't needed any more.

(in reply to: ↑ 33 ) 10/15/08 22:42:14 changed by jacobsantos

Replying to westi:

Replying to jacobsantos:

Can this still go in? Or does it need to be pushed to 2.8?

Thanks for updating my ancient patch. I think this can push to future for now. I suspect we may have enought other functionality around now that this isn't needed any more.

Explain please. Do you mean they can use the get_plugin_data() function instead? If so, then I kind of agree and this ticket can be closed as won't fix.