Answers:
is_plugin_active()
相当脆弱:当插件作者重命名主文件或用户重命名插件的目录或主文件时,它会中断。最好检查是否存在某个公共功能。
为了避免每次需要一些插件功能时都必须进行检查,可以在管理区域中显示一条消息:
add_action( 'admin_notices', 'my_theme_dependencies' );
function my_theme_dependencies() {
if( ! function_exists('plugin_function') )
echo '<div class="error"><p>' . __( 'Warning: The theme needs Plugin X to function', 'my-theme' ) . '</p></div>';
}
另一种选择是使用类似http://tgmpluginactivation.com/的东西
虽然这并不能防止在禁用插件时破坏主题,但我会看一下有关“如何显示所需主题的管理通知”插件的文章。我从来没有对主题强制安装插件的想法感到满意,因此这似乎是下一个最佳选择。
另一个很快的想法:我从未尝试过这种方法,但是我想知道您是否可以找到一种巧妙的方法来在单个条件中容纳多个钩子。也许您可以将所有条件函数放在一个不同的文件中,并且仅在if( function_exists( 'plugin_function' ) )
返回时才需要它true
(但要了解这是不完善的检查。)
如果只需要一个插件页面,则有is_plugin_active()
。如果您在外部需要它,则最好将核心功能复制/粘贴到您的主题中,然后重新使用它:
if ( ! is_admin() )
{
/**
* Check whether the plugin is active by checking the active_plugins list.
*
* @since 2.5.0
*
* @param string $plugin Base plugin path from plugins directory.
* @return bool True, if in the active plugins list. False, not in the list.
*/
function is_plugin_active( $plugin ) {
return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}
有条件的避免了双重定义函数的任何错误。
if(function_exist('plugin_function'))
与if(is_plugin_active('plugin-file.php'))
注意:此答案仅用于简化@scribu和@kaiser之间的讨论。Mods:请不要删除。用户/读者:请不要投票。如果要关注讨论,请查看修订/编辑日志。如果要加入讨论,请编辑答案。如果讨论有结果,那么它将被标记为这样。谢谢。
在某些情况下,权重也有所不同,您可能会有插件依赖性。(这些示例只是虚构的)。从父母的角度来看,“(父母)插件”一词可以与“主题”交换。
在下面的内容中,我尝试概述当您更新“其他”插件并且检查不再起作用时会发生什么。
如果您想知道插件是否处于活动状态,可以检查三种可能的恕我直言:
'active_plugins'
- 是否存在?如果现在以我的内部链接检查器插件为例,它不提供公共API并且不打算扩展,那么我将没有理由(作为作者)不按需或随便更改内部函数命名。因此,如果有人尝试搭载此插件,则更新时东西就会断裂(取决于功能和捆绑的紧密程度)。文件名也是如此。我没有真正的理由(除了该插件会在更新时停用),而不更改文件名。唯一使我无法更改文件夹名称的事情是,更新检查和通知将针对文件名运行-如果该文件位于官方存储库中。
因此,我想说(父)插件从最弱(易于更改)到最困难(很多反对更改)的部分是:
功能»主文件名»文件夹
当我说一个函数检查比使用它不那么脆弱时,is_plugin_active()
我认为问题函数是插件作者明确鼓励的。最终的示例是wp_pagenavi()
WP-PageNavi插件提供的模板标签。
定义依赖项的困难在于,没有标准的方法来唯一地标识不涉及文件名的插件。
关于此主题的更多想法:
我想到目前为止,我们可以概括为三点:
我可以考虑的(到目前为止)最聪明的方法,已经在一些(太少了)插件中看到了:
// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );
无需过多考虑,但我想您可以将通知挂接到“ all”过滤器的检查中,并检查当前过滤器内部是否在shutdown
挂机时触发了它...?
对于“正常”和“弱”依赖项,使用钩子效果很好。唯一的缺点是,如果不满足依赖项,您仍将需要使用
function_exists()
或is_plugin_active()
停止。为此,使用“全部”过滤器将过于昂贵。
@scibu这是针对“您的”主题的。(我已经放弃谈论我的了)。:)
因此,基本上,如果您需要依赖项-并且您有一个不错的作者-那么他可以提供钩子代替模板标签。因为只有在存在钩子的情况下,插件才会钩住它,否则什么也不做。另一方面,当插件不存在时,您也不会出错。
这是困难的部分(或更多的问题):要编写管理员通知以告知用户依赖性“您需要安装»DisneyWonderLinks«”,可以选中array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] )
。我不确定这是否行得通,但是afaik该数组应该在(公共/管理员)双方都可以访问。
那行不通。仅仅因为回调已注册到钩子并不意味着该钩子将在预期时被触发。唯一可以进行类似工作的是使用“关机”钩子,您之前已经提到过:
add_action( 'shutdown', function() {
if ( !did_action( 'template_tag_like_hook' ) )
echo 'Problem.';
} );
当然,此</html>
标签将打印在标签之后的最底部,前端(因为通常使用模板标签),因此没有太大用处。
您可以尝试将消息存储在wp_options中,然后在管理区域中显示该消息,但这将打开一堆全新的蠕虫病毒:无效,缓存插件等。
function_exists
,那么普通用户将仅收到一条消息,即他尚未安装另一个插件依赖的插件。问题是,用户实际上会安装该插件,然后想知道为什么它不起作用。哦,我不会为此而投票。