分类
原创

解决WordPress无法自动更新插件及主程序问题

最近升级到WordPress2.7后,有一个一直困扰我的问题终于到了不得不解决的时候了。

问题描述:

  1. 使用WordPress2.7的自动升级功能时,提示:You do not have sufficient permissions to update plugins for this blog或者:您没有权限更新插件。
  2. 在插件管理页面,如果有插件更新,应该会自动提示,并有一个直接升级的选项。但在某次升级后,该选项消失。只能手动FTP更新插件。

问题分析

(不想看分析的同学,请直接拖拉到后面的解决方案):

今年WordCamp期间,LEMONed同学怀疑是文件版本不协调或不完整,建议我重新安装整个WordPress来解决这个问题。但是尝试后,无效。

后来怀疑是帐号权限问题,经过检查数据库,发现自己的帐号确实是Administrator,帐号等级也是最高的10.这条路,也死了。

就这样,这个问题放了3个月,直到前几天更新了WordPress2.7。在这次的更新里,我最喜欢的就是主程序自动更新功能,但如插件一样,无法更新。

但这一次的问题比上一次清晰了很多,因为主程序更新是靠wp-admin\update-core.php这个文件实现的。既然是这里报了错,那么我们就从这个文件开始分析吧。

我分析了一下update-core那个文件,第一句就要判断if ( ! current_user_can(‘update_plugins’) )
再去capabilities.php里面看了看current_user_can这个函数,发现是一个权限分配函数,判断方法有点诡异(hc才疏学浅,没见识过这类权限分配方法),结合codex的数据库结构看了半天才看懂:

function current_user_can( $capability ) {
    $current_user = wp_get_current_user();

    if ( empty( $current_user ) )
        return false;

    $args = array_slice( func_get_args(), 1 );
    $args = array_merge( array( $capability ), $args );

    return call_user_func_array( array( &$current_user, ‘has_cap’ ), $args );
}

一开始以为它应该是通过储存在数据库usermeta这张表里的某些信息来判定当前用户是否拥有某些权限。

可是没找到update_plugins这个权限在数据库的对应位置,所以我开始思考是否这些权限是由一个数组构成,每个权限有一个对应编号。但是按着这个思路,也没有发现什么有价值的内容。

然后开始在数据库里一张张表的闲逛,突然想到wp_get_current_user这个函数是从哪取数据呢?然后就沿着这条线发现了在options这张混乱不堪的表里有一个很重要的参数:wp_user_roles

这个参数在codex里没有详细的说明,所以只有靠自己摸索。从结构来看,这个参数的值还算好理解,类似于一个XML文档,树形的。每个角色应该拥有什么权限,全都在这里。

我仔细检查了一个全新WordPress2.7数据库与我数据库option表下wp_user_roles的区别,发现我的数据库缺少update_plugins和delete_plugins这两个权限。至此,问题分析结束。

查阅Codex得知,update-plugin这一项是从2.6才加入的。可能因为某次跨越升级,或者升级不完善,或者恢复了老的数据库,导致我的表这个地方没有update-plugin这一项,自己添加上应该就ok了。

解决方案

知道了问题所在之后,解决起来自然是相当简单。

1.进入phpmyadmin,找到wp_options(默认你的表前缀是wp,如果不是,请去你自己前缀下的options)表下的wp_user_roles,点击该项前面的修改按钮。

2.你会发现这里多个角色的权限分配,不要管后面的,找到b:1;}}s:6:”editor”这样的代码,在这句代码之前插入b:1;s:14:”update_plugins”;b:1;s:14:”delete_plugins”;这样一句代码,理论上问题就该解决。可是事实上,你会发现自己无法进入后台了。别急,还有一步。

3.当时我也比较头痛,为什么理论上能解决问题的方法反倒让自己进不了后台了。想到前面把这个属性比作XML文件的想法,对这些数值那些奇怪的a:5:{s:13一类字符进行了分析。

原来答案很简单,a就是数组,代表后面括号内有多少元素;s当然就是字符串,表示后面引号内的字符串长度;b应该是空格。所以在我们增添了b:1;s:14:”update_plugins”;b:1;s:14:”delete_plugins”;这样一句代码后,事实上是给这个数组增添了2个元素,相应的,我们得去前面修改这个数组的元素数量。

4.找到整个参数中第一句s:12:”capabilities”;a:。将a冒号后面的数字加2即可。比如原本是54,你就改为56。

5.大功告成,快去享受WordPress2.7带来的全新自动升级功能吧!

后记

这个问题从今年9月拖到现在,请教了很多朋友,但谁会想到是这么一个扯淡的问题。如果不花时间自己多Google,研究Codex,分析数据库结构,是无法解决这类尴尬问题的。

所以在这个信息触手可及的时代,求人不如求己,多多动手动脑才是解决问题的王道。

“解决WordPress无法自动更新插件及主程序问题”上的11条回复

感谢这么快回复。
第三步我也做了的,现在已经搞定了。
其实很简单,把引号改为英文的就行,当时光顾着复制,没仔细看,修改过,马上好了。
现在已经能够成功升级了,嘿嘿

[…] 最近花了点时间研究了一下这个问题,最后在这里才看到问题原因,应该是因为之前从很低的版本直接跨越升级,数据库中wp_user_roles的参数缺失造成的,同样在这里也给出了解决的办法,不过自己对数据库的操作还是不太熟悉,还是用了笨办法直接重新安装wordpress了,还好有wordpress的导入导出功能…看来以后还是老老实实一个一个版本升级的好%>_< % […]

[…] 最近抽空研究了一下这个问题,最后在这里才找到问题原因的说明,应该是因为之前从很低的版本直接跨越升级,wordpress的数据库中wp_user_roles的参数缺失造成的,同样在这里也给出了解决的办法,不过自己对数据库的操作还是不太熟悉,还是用了笨办法直接重新安装wordpress了,还好有wordpress的导入导出功能…看来以后还是老老实实一个一个版本升级的好. […]

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注