Note: This answer is just here to make discussion between @scribu and @kaiser easier. Mods: Please don't delete. Users/Readers: Please don't vote. If you want to follow the discussion, take a look at the revision/edit log. If you want to join the discussion, edit the Answer. If the discussion has a result, then it will be marked as such. Thank you.
Scenarios
There are also different scenarios that weight different, where you could have a plugin dependency. (The examples are only fictional). The word "(parent) Plugin" can be exchanged with "Theme" from parent point of view.
- (hard) A child plugin that only extends the functionality or alters the display (and similar) of an existing plugin and therefore can't exist without the parent. Example: BuddyPress » BuddyPress-FunkyCommentDisplay
- (normal) A plugin that has extended functionality when a child plugin is activated. Example: jQueryAttachmentCarousel » jQuerySlideDeck
- (soft) A plugin that just adds a feature. Example: DisneyWonderlandTheme » MickeysSocialLinks
In the following I try to sketch what happens when you update the "other" plugin and the check doesn't work anymore.
- Ad 1) The plugin couldn't exist without BuddyPress activated » Stuff is completely broken.
- Ad 2) The plugin couldn't offer the option to switch from Carousel to SlideDeck » Displays wired (I assume that styles are modified to SlideDeck).
- Ad 3) MickeysSocialLinks disappear.
Check
There are imho three possibilities to check against, if you want to know if a plugin is active:
- A. Does the folder exist?
- B. Does the main file - option
'active_plugins'
- exist?
- C. Does a particular function exist?
If I now take my Internal Link Checker Plugin as an example, that offers no public API and isn't meant to get extended, then I'd see no reason (as author) to not change internal function naming on demand or just on will. So if someone would try to piggyback on this plugin, then stuff would simply break (depending on functionality and tightness of bundling) on update. The same goes for file names. I'd have no real reason (aside from that the plugin would get deactivated on update) to not change the filename. The only thing that would hold me back from changing the folder name is that the update check & notification runs against the file name - if it's hosted in the official repo.
So I'd say from weakest (easy to change) to toughest (a lot speak against changing) part of a (parent) plugin would be:
function » main file name » folder
When I said that a function check is less fragile than using is_plugin_active()
I assumed that the function in question is one that the plugin author explicitly encourages. The ultimate example of this would be the wp_pagenavi()
template tag offered by the WP-PageNavi plugin.
The difficulty in defining dependencies is that there's no standard way to uniquely identify plugins that doesn't involve file names.
More thoughts on the subject:
http://wordpress.org/support/topic/plugin-plugin-dependencies-unreliable-plugin-namingidentifying-scheme
I guess we can so far sum it up in three points:
- We have talked about slightly different topics
- We agree that there's no bulletproof way to get around what I thought the topic would be
- From your understanding of the question, you offered on valid way to go
The (so far) smartest way I can think off, that I've already seen in some (much too less) plugins:
// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );
Without thinking too much in detail about it, but I guess you could hook your notice into a check on 'all' filter and check inside current filter if it was triggered when you are on the shutdown
hook...?
Using hooks would works well for 'normal' and 'weak' dependencies. The only drawback is that you would still need to use function_exists()
or is_plugin_active()
if you want to stop if the dependency is not met. Using the 'all' filter for that would be too expensive IMO.
@scibu This was targeted at "your" topic. (I already dropped talking about mine). :)
So basically, if you need a dependency - and you have a nice author - then he could offer a hook instead/as replacement for a template tag. Because the plugin would only hook into it if the hook would be present, or simply do nothing. And on the other side you wouldn't have an error, when the plugins not present.
Here's the tough part (or more of a Q): To write an admin notice to inform the user about the dependancy "You need to install »DisneyWonderLinks«", you could check the array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] )
. I'm not sure if this would work, but afaik the array should be accessible on both (public/admin) sides.
That would not work. Just because a callback is registered to a hook doesn't mean that the hook will be triggered when expected. The only thing that would sort-of-kind-of work is using the 'shutdown' hook, which you mentioned before:
add_action( 'shutdown', function() {
if ( !did_action( 'template_tag_like_hook' ) )
echo 'Problem.';
} );
Of course, this would be printed at the very bottom, after the </html>
tag, on the front-end (since that's where template tags are normally used), which is not of much use.
You could try to store the message in wp_options and then display it in the admin area, but that would open a whole new can of worms: invalidation, caching plugins etc.