WordPress.org

Make WordPress Core

Opened 9 years ago

Closed 6 years ago

#3047 closed enhancement (wontfix)

get_plugininfo()

Reported by: forceagainstsomething Owned by: jacobsantos
Milestone: Priority: normal
Severity: normal Version: 2.1
Component: Plugins Keywords: has-patch needs-testing
Focuses: 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 (5)

get_plugininfo.diff (3.0 KB) - added by forceagainstsomething 9 years ago.
get_plugininfo() patch
3047.diff (5.1 KB) - added by westi 9 years ago.
Alternative implementation of get_plugin_info
get_plugininfo.php (1.4 KB) - added by forceagainstsomething 9 years ago.
3047a.diff (4.4 KB) - added by westi 9 years ago.
Replacement patch as descirbed in my comment
3047.r9125.diff (2.9 KB) - added by jacobsantos 7 years ago.
Updated westi patch for r9125 and new get_plugin_data() function.

Download all attachments as: .zip

Change History (41)

@forceagainstsomething9 years ago

get_plugininfo() patch

comment:1 @forceagainstsomething9 years ago

  • Version set to 2.1

comment:2 @war593129 years ago

Very nice! :)

comment:3 @westi9 years ago

+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?

comment:4 @forceagainstsomething9 years ago

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.

comment:5 @RuddO9 years ago

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.

comment:6 @RuddO9 years ago

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 =)

comment:7 @ryan9 years ago

debug_backtrace requires PHP 4.3. We support 4.2.

comment:8 @forceagainstsomething9 years ago

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).

comment:9 @ryan9 years ago

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.

@westi9 years ago

Alternative implementation of get_plugin_info

comment:10 @westi9 years ago

  • Keywords bg|has-patch bg|dev-feedback added
  • 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.

comment:11 @forceagainstsomething9 years ago

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.

comment:12 @westi9 years ago

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.

comment:13 @forceagainstsomething9 years ago

"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.

comment:14 @forceagainstsomething9 years ago

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.

comment:15 @markjaquith9 years ago

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).

comment:16 @masquerade9 years ago

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

comment:17 @westi9 years ago

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.

@westi9 years ago

Replacement patch as descirbed in my comment

comment:18 @forceagainstsomething9 years ago

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+.

comment:19 @westi9 years ago

"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.

comment:20 @masquerade9 years ago

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.

comment:21 @forceagainstsomething9 years ago

"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.

comment:22 follow-up: @_erik_8 years ago

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.

comment:23 @foolswisdom8 years ago

  • Keywords has-patch dev-feedback added; bg|has-patch bg|dev-feedback removed
  • Milestone set to 2.4

comment:24 in reply to: ↑ 22 ; follow-up: @JeremyVisser8 years ago

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 __().

comment:25 in reply to: ↑ 24 @rob1n8 years ago

  • 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.

comment:26 @_erik_8 years ago

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

comment:27 @westi8 years ago

  • Keywords has-patch removed
  • 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.

comment:28 @westi7 years ago

  • Keywords needs-patch added; dev-feedback removed
  • Milestone changed from 2.4 to 2.6

Pushing off into the future for now.

I will look at this later

comment:29 @jacobsantos7 years ago

  • Owner changed from westi to jacobsantos
  • Status changed from assigned to new

comment:30 @jacobsantos7 years ago

  • Status changed from new to assigned

@jacobsantos7 years ago

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

comment:31 @jacobsantos7 years ago

  • Keywords has-patch needs-testing added; needs-patch removed

comment:32 follow-up: @jacobsantos7 years ago

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

comment:33 in reply to: ↑ 32 ; follow-up: @westi7 years ago

  • 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.

comment:34 in reply to: ↑ 33 ; follow-up: @jacobsantos7 years ago

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.

comment:35 @jacobsantos6 years ago

  • Component changed from Administration to Plugins

comment:36 in reply to: ↑ 34 @westi6 years ago

  • Milestone 2.8 deleted
  • Resolution set to wontfix
  • Status changed from assigned to closed

Replying to 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.

Yes Yes Yes.

Note: See TracTickets for help on using tickets.