我对Wordpress插件开发还比较陌生,我已经阅读了Wordpress Codex,但是在最佳实践和简单的卸载功能示例之外,我对用户实际卸载时插件的工作方式了解不多它。
我希望实现的是,当用户卸载我的插件时,会出现一个弹出窗口,询问他们是否要删除插件文件或插件文件以及插件已上传到其站点的所有内容。为了获得更多上下文,我的插件的主要功能是将存储在单独服务器上的数据作为帖子迁移到用户的wordpress实例中,如果用户选择该选项,这些帖子就是我要删除的内容。
以下是我当前的卸载设置,当我在wordpress中单击“卸载”时,wordpress确实卸载了我的插件(从其目录中删除了插件文件夹和文件),但在此过程中未显示弹出窗口。我本来以为这是样式问题,但是没有加载弹出文件中的HTML。我还检查了文件路径变量,它是正确的路径。因此,我不确定是什么原因阻止了弹出窗口的显示,并不允许用户选择是否应将内容与插件一起删除。
在此问题上的任何帮助或见解将不胜感激!
uninstall.php
<?php
//checks to make sure Wordpress is the one requesting the uninstall
if (!defined('WP_UNINSTALL_PLUGIN')) {
die;
}
$my_plugin_file_path = trailingslashit(plugin_dir_path(__FILE__));
include $my_plugin_file_path . 'templates/my-plugin-uninstall-popup.php';
my-plugin-uninstall-popup.php
<!-- styling for popup -->
<!-- end of styling for popup -->
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="myModalLabel">Uninstall popup</h2>
</div>
<div class="modal-body">
<form action="<?php echo esc_url( $my_plugin_file_path . 'my-plugin-uninstall-executor.php' ); ?>" method="post">
<label>Do you want to remove the content that this plugin has uploaded?</label>
<input id="delete-content-yes" name="delete-content" value="YES" type="radio" />Yes
<input id="delete-content-no" name="delete-content" value="NO" type="radio" />No
<input type="submit" name="submit" value="Submit" />
</form>
</div>
</div>
</div>
my-plugin-uninstall-executor.php
<?php
if (isset($_POST['delete-content']) && $_POST['delete-content'] === 'YES')
//delete content from user's wordpress db
答案 0 :(得分:2)
不幸的是,据我所知,目前还没有官方钩子来显示自定义卸载屏幕。
在旧版本的WordPress中,曾经有一个“卸载确认”屏幕-尽管我很确定也没有办法将其钩住-但如今,WordPress只是显示了一个JS确认框(“ 您要在运行uninstall.php
(如果找到)并删除其文件之前删除[插件名称]及其数据?“)。
在这种情况下,我看到其他插件开发人员所做的是在插件的“设置/配置”页面中包含一个自定义的“卸载”屏幕,该屏幕使他们可以执行您在问题中所描述的内容。这不是理想的解决方案,因为某些用户可能不知道自定义卸载屏幕,因此可能会以“传统”方式卸载该插件,因此您将无法显示确认屏幕/弹出窗口,但这是您的最佳选择这次。
如果您想进一步this answer tells you how to uninstall a plugin programatically。现在(2011年)已经相当老了,但是如果仍然有效,那么也许您可以在运行自定义操作后删除自己的插件。
答案 1 :(得分:1)
do_action( 'pre_uninstall_plugin', function( $plugin ) {
if ( $plugin === 'path to your main plugin file from plugins directory' ) {
wp_redirect( 'url of your custom uninstall script' );
exit();
}
} );
这将中止内置的wordPress卸载代码,并且您的自定义卸载脚本可以执行您想要的任何操作,但是您当然需要实现很多代码,如果您不太了解WordPress,但是这样做会很困难。这将使您学习到很多有关WordPress如何在管理员模式下工作的信息。
附录
进一步考虑,我认为这很容易做到。您的自定义脚本应在自定义管理页面中显示您的表单。提交此表单可以将您的设置临时保存在wp_options表中,然后重定向到原始的删除URL。如果存在瞬变,请在操作“ pre_uninstall_plugin”中执行任何操作,然后让WordPress调用您的卸载脚本。当然,您的卸载脚本应从wp_options表中的瞬态读取设置并进行相应处理。重定向回原始的删除URL将使WordPress处理删除插件的通用部分,而卸载脚本仅需要处理删除插件的特定于插件的部分。如果此删除是作为批量删除请求的一部分进行的,则在重定向之前,您应该通过删除以前删除的插件来清理原始删除URL。
从添加到添加
事实上,有可能做得更好。基本思想是拦截插件删除请求,将HTTP重定向到配置删除请求的页面,将删除配置保存到数据库,然后对原始删除请求进行HTTP重定向。调用插件的卸载脚本时,它将从数据库中读取其删除配置,并进行相应的删除。在这种情况下,应尽早进行拦截,因此操作“ admin_init”将是一个不错的选择。早期拦截的优势在于,如果插件是作为批量请求的一部分删除的,因为拦截是在处理任何内容之前完成的,所以原始删除URL仍然有效,因此您不必担心以前删除的插件。
要实现此解决方案,有很多代码需要编写,我没有时间去做,但是我可以向您概述要做什么。
使用add_submenu_page()创建一个管理页面来配置插件的卸载。尽管此页面将通过HTTP重定向调用,但管理页面是通过挂钩调用的,并且此挂钩要求在全局$菜单中有一个条目。 add_submenu_page()在此仅用于为将显示管理页面的功能在全局$菜单中创建一个条目。也不需要创建的菜单项,并且可以将其隐藏。
对'admin_init'使用操作可拦截对插件的删除请求。删除请求如下所示。
您可以使用$ _SERVER和$ _GET全局变量来帮助您解析请求URL。 (在这里全局$ pagenow可能有用。)如果请求是对插件的删除请求。使用wp_redirect()将HTTP重定向到使用add_submenu_page()创建的管理页面。使用urlencode编码后,您需要将原始URL作为查询参数传递给管理页面。您的管理页面的网址如下所示。
http://aaa.bbb.ccc/wp-admin/admin.php?page=your-settings-page
您可以从菜单项中获得此URL,因为它只是HTML A元素的href。
您的管理员页面处理程序应显示您的设置表单,用于配置插件的卸载。您可以将原始删除URL作为隐藏的输入字段进行传递,因此在提交此表单时,它也会发送原始删除URL。
提交的表单的处理程序应使用set_transient()将设置保存为数据库中的瞬态。然后,应该对原始删除网址执行wp_redirect()。
“ admin_init”处理程序将再次被调用,并应检查是否已设置了瞬态,是否已设置了瞬态,则不让WordPress处理删除请求。
您的卸载脚本应从数据库读取瞬态并进行相应处理,然后从数据库中删除瞬态。
答案 2 :(得分:0)
或者,您可以使用jQuery拦截对“删除” HTML A元素的单击,并显示您的表单。然后使用AJAX请求将您的删除设置临时保存在wp_options表中。当AJAX请求返回时,您可以转发到原始的删除URL。您的卸载脚本需要读取以前保存在瞬态中的删除设置。
此方法涉及的代码较少,但取决于HTML delete元素(当前为类'delete'的HTML A元素)的特定HTML实现。由于WordPress可以更改此实现,因此这种方法在升级方面并不安全。当然,这不适用于批量删除,但是在这种情况下,您可以拦截批量删除操作并显示您的表单,然后像以前一样进行操作。