WordPress4.2升级修复补丁:解决大量404请求以及评论表情路径及尺寸异常问题

上一篇文章写到了 WordPress 升级 4.2 版本后部分主题出现了大量 404 请求的问题,匆忙解决也没深究原因。今天继续调试主题却发现了评论表情不显示了,看来又是 4.2 惹的祸了!

于是埋头折腾,总算把问题解决了,为了方便遇到和我一样问题的站长,张戈特意将修复方法整理成 PHP 补丁,降低修复难度,如果你也遇到此类问题,且往下看。

一、前因后果

这次 WordPress 升级 4.2 总体来说没有以前版本升级来得顺畅,目前已发现如下 3 个问题:

  1. 有部分主题的前台会产生大量的 404 错误请求(站外资源);
  2. 评论表情名称变更导致表情无法显示或者无法通过钩子更改;
  3. 外观-->菜单-->显示选项-->点不出来(已有修复方法,猛戳直达==>)。

第 1 个问题:分析了一下原因,和以前出现的谷歌字体加载卡出翔的情况类似,部分主题可能触发了 4.2 新增的 CDN 功能,在前台插入了国外 CDN 资源,不巧却被厚实 GFW 关门闭客了,而且居然还有重试机制,于是就产生了大量的错误请求!

第 2 个问题:其实是因为 4.2 对评论表情的重构(样式变更、名称变更、CDN 机制等)造成的。和第 1 个问题有所关联,都不约而同的和 4.2 下的 emoji 关键标签挂上了钩。emoji 这个玩意我暂时还没有去研究是啥新玩意,但从目前的情况来看,这个玩意暂时不适合天朝环境。。。

张戈博客上一篇文章《解决 WordPress 升级 4.2 后调用国外图片导致大量 404 请求的问题》已经粗略分享了解决办法,不过在下文中还会分享一个整体修复补丁。

正对第 2 个问题,下面说一下手动修复方法。

二、修复思路

表情名称重构了,所以我们需要找到那个表情过滤函数,然后改变它。我们知道评论表情里面有名为 mrgreen 的表情代号,所以最笨最有效的方法就是在 WordPress 全局搜索存在这个关键词的 php 文件(可以在 Linux 下 grep,也可以在 Windows 下借用 UE 或 Editor ++等),幸不辱命,总算顺藤摸瓜找到症结所在!

①、表情名称变更

问题截图:

通过搜索,我找到了这个将代号过滤成表情文件的函数 smilies_init ,位于 wp-includes/functions.php 文件中。

老版本代码:

新版本代码:

明显把文件名称给改了,所以修复方法就是用老版代码替换新版本代码即可。

②、表情尺寸异常

解决表情不显示问题之后,发现这表情尺寸也醉了:

先让我感叹一下,老外的视力素质真的都这么好吗?反正我是觉得太小了。。。

还是老方法,全局搜索 height: 1em; max-height: 1em ,立竿见影!在 wp-includes/formatting.php 找到 3 处相关代码。

先手动修改后发现还是不凑效,于是继续检查,发现网站前台还输出了一个表情样式定义:

<style type="text/css">
img.wp-smiley,
img.emoji {
	display: inline !important;
	border: none !important;
	box-shadow: none !important;
	height: 1em !important;
	width: 1em !important;
	margin: 0 .07em !important;
	vertical-align: -0.1em !important;
	background: none !important;
	padding: 0 !important;
}
</style>

于是继续全局搜索以上代码中的关键词,于是又找到了 print_emoji_styles() 函数,在通过函数名找到调用地方,手动注释后发现可以解决问题:

接下来就是发现问题就依葫芦画瓢解决问题问题的过程,最终全部搞定!

动手能力强的朋友估计已经去折腾去了,如果你觉得这样很麻烦,那就继续往下看吧!

三、修复补丁

这样修改不但麻烦,而且一旦 WP 更新,统统失效,所以张戈整理成一个 php 补丁,分享给大家,只要集成到主题中就可以解决这些问题了!

下载地址

具体代码如下:

<?php
/**
 * 修复WordPress升级4.2带来的各种问题 By 张戈博客
 * 原文地址①:http://zhangge.net/5034.html 
 * 原文地址②:http://zhangge.net/5035.html
 * 修复说明:
 * ①、部分主题出现大量404请求
 * ②、修复表情路径异常问题
 * ③、后续遇到问题将继续更新
 * */
remove_action( 'wp_head','print_emoji_detection_script',7);     //解决4.2版本部分主题大量404请求问题
remove_action('admin_print_scripts', 'print_emoji_detection_script'); //解决后台404请求
remove_action( 'init',       'smilies_init',               5);  //移除4.2版本表情钩子
remove_action( 'wp_print_styles',   'print_emoji_styles'    );  //移除4.2版本前台表情样式钩子
remove_action( 'admin_print_styles',    'print_emoji_styles');  //移除4.2版本后台表情样式钩子
remove_action( 'the_content_feed',      'wp_staticize_emoji');  //移除4.2 emoji相关钩子
remove_action( 'comment_text_rss',      'wp_staticize_emoji');  //移除4.2 emoji相关钩子
remove_action( 'comment_text',      'convert_smilies',   20 );  //移除4.2 表情相关钩子
remove_action( 'the_content',           'convert_smilies'   );  //移除4.2 表情相关钩子
remove_action( 'the_excerpt',            'convert_smilies'  );  //移除4.2 表情相关钩子
 
add_action( 'comment_text',     'convert_smilies_diy',    20);  //自定义表情相关钩子
add_action( 'the_content',          'convert_smilies_diy'   );  //自定义表情相关钩子
add_action( 'the_excerpt',      'convert_smilies_diy'       );  //自定义表情相关钩子
add_action( 'init',         'smilies_init_old',     5       );  //自定义表情钩子
 
//原函数 smilies_init 位于wp-includes/functions.php
function smilies_init_old() {
	global $wpsmiliestrans, $wp_smiliessearch;
	// don't bother setting up smilies if they are disabled
	if ( !get_option( 'use_smilies' ) )
		return;
	if ( !isset( $wpsmiliestrans ) ) {
		$wpsmiliestrans = array(
		':mrgreen:' => 'icon_mrgreen.gif',
		':neutral:' => 'icon_neutral.gif',
		':twisted:' => 'icon_twisted.gif',
		  ':arrow:' => 'icon_arrow.gif',
		  ':shock:' => 'icon_eek.gif',
		  ':smile:' => 'icon_smile.gif',
		    ':???:' => 'icon_confused.gif',
		   ':cool:' => 'icon_cool.gif',
		   ':evil:' => 'icon_evil.gif',
		   ':grin:' => 'icon_biggrin.gif',
		   ':idea:' => 'icon_idea.gif',
		   ':oops:' => 'icon_redface.gif',
		   ':razz:' => 'icon_razz.gif',
		   ':roll:' => 'icon_rolleyes.gif',
		   ':wink:' => 'icon_wink.gif',
		    ':cry:' => 'icon_cry.gif',
		    ':eek:' => 'icon_surprised.gif',
		    ':lol:' => 'icon_lol.gif',
		    ':mad:' => 'icon_mad.gif',
		    ':sad:' => 'icon_sad.gif',
		      '8-)' => 'icon_cool.gif',
		      '8-O' => 'icon_eek.gif',
		      ':-(' => 'icon_sad.gif',
		      ':-)' => 'icon_smile.gif',
		      ':-?' => 'icon_confused.gif',
		      ':-D' => 'icon_biggrin.gif',
		      ':-P' => 'icon_razz.gif',
		      ':-o' => 'icon_surprised.gif',
		      ':-x' => 'icon_mad.gif',
		      ':-|' => 'icon_neutral.gif',
		      ';-)' => 'icon_wink.gif',
		// This one transformation breaks regular text with frequency.
		//     '8)' => 'icon_cool.gif',
		       '8O' => 'icon_eek.gif',
		       ':(' => 'icon_sad.gif',
		       ':)' => 'icon_smile.gif',
		       ':?' => 'icon_confused.gif',
		       ':D' => 'icon_biggrin.gif',
		       ':P' => 'icon_razz.gif',
		       ':o' => 'icon_surprised.gif',
		       ':x' => 'icon_mad.gif',
		       ':|' => 'icon_neutral.gif',
		       ';)' => 'icon_wink.gif',
		      ':!:' => 'icon_exclaim.gif',
		      ':?:' => 'icon_question.gif',
		);
	}
	if (count($wpsmiliestrans) == 0) {
		return;
	}
	/*
	 * NOTE: we sort the smilies in reverse key order. This is to make sure
	 * we match the longest possible smilie (:???: vs :?) as the regular
	 * expression used below is first-match
	 */
	krsort($wpsmiliestrans);
	$spaces = wp_spaces_regexp();
	// Begin first "subpattern"
	$wp_smiliessearch = '/(?<=' . $spaces . '|^)';
	$subchar = '';
	foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
		$firstchar = substr($smiley, 0, 1);
		$rest = substr($smiley, 1);
		// new subpattern?
		if ($firstchar != $subchar) {
			if ($subchar != '') {
				$wp_smiliessearch .= ')(?=' . $spaces . '|$)';  // End previous "subpattern"
				$wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern"
			}
			$subchar = $firstchar;
			$wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:';
		} else {
			$wp_smiliessearch .= '|';
		}
		$wp_smiliessearch .= preg_quote($rest, '/');
	}
 
	$wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';
}
//原函数 convert_smilies 位于wp-includes/formatting.php
function convert_smilies_diy( $text ) {
	global $wp_smiliessearch;
	$output = '';
	if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) {
		// HTML loop taken from texturize function, could possible be consolidated
		$textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between
		$stop = count( $textarr );// loop stuff
		// Ignore proessing of specific tags
		$tags_to_ignore = 'code|pre|style|script|textarea';
		$ignore_block_element = '';
		for ( $i = 0; $i < $stop; $i++ ) {
			$content = $textarr[$i];
			// If we're in an ignore block, wait until we find its closing tag
			if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) )  {
				$ignore_block_element = $matches[1];
			}
			// If it's not a tag and not in ignore block
			if ( '' ==  $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) {
				$content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley_diy', $content );
			}
			// did we exit ignore block
			if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content )  {
				$ignore_block_element = '';
			}
			$output .= $content;
		}
	} else {
		// return default text.
		$output = $text;
	}
	return $output;
}
//原函数 translate_smiley 位于wp-includes/formatting.php
function translate_smiley_diy( $matches ) {
	global $wpsmiliestrans;
	if ( count( $matches ) == 0 )
		return '';
	$smiley = trim( reset( $matches ) );
	$img = $wpsmiliestrans[ $smiley ];
	$matches = array();
	$ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
	$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
	// Don't convert smilies that aren't images - they're probably emoji.
	if ( ! in_array( $ext, $image_exts ) ) {
		return $img;
	}
	/**
	 * Filter the Smiley image URL before it's used in the image element.
	 *
	 * @since 2.9.0
	 *
	 * @param string $smiley_url URL for the smiley image.
	 * @param string $img        Filename for the smiley image.
	 * @param string $site_url   Site URL, as returned by site_url().
	 */
        //请注意!已将表情路径定义到主题目录下的 images/smilies 文件夹
	$src_url = apply_filters( 'smilies_src', get_bloginfo('template_directory').'/images/smilies/'.$img, $img, site_url() );
	return sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="/*height: 1em; max-height: 1em;*/" />', esc_url( $src_url ), esc_attr( $smiley )         );
    }
?>

将下载的文件解压,并查看代码倒数第 5 行中的表情路径和你主题所用表情是否对应,若不对应请自行根据实际情况修改 /images/smilies 指向你的表情文件夹即可(若没有表情文件,请从本文下载并上传到主题目录亦可)。

然后上传到主题目录,修改主题目录下的 functions.php,在最后一个?>之前新增如下调用代码即可:

//4.2 修复补丁,请注意 patch_to_4.2.php 路径是否正确。
include("patch_to_4.2.php");

保存后,去前台刷新应该就一切正常了。

四、惯例总结

本次 WordPress 升级感觉改动还是挺大的,所以肯定也存在不少 BUG,尤其是在格格不入的天朝环境下更是容易出现一些卡出翔的问题。不过 WordPress 在天朝的使用率如此之高,相信官方很快就会更新下一个版本,来修复诸如此类的问题。

张戈也算是一个狂热的 WordPress 折腾爱好者,所以在官方修复之前先将自己的折腾成功分享出来,让更新出现问题的站长提前解决这些烦人的问题。

好了,就说这么多了,如果你更新后没有这些问题,就当本文分享的是一个解决 WordPress 网站故障的一个思路吧!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PPV课数据科学社区

QQ空间(日志、说说、个人信息)python爬虫源码(一天可抓取 400 万条数据)

爬虫功能: QQSpider 使用广度优先策略爬取QQ空间中的个人信息、日志、说说、好友四个方面的信息。 判重使用“内存位”判重,理论上亿数量级的QQ可瞬间判...

5275
来自专栏轮子工厂

有哪些实用且堪称神器的Chrome插件?吐血推荐!!!

相信很多人都在使用 Chrome 浏览器,其流畅的浏览体验得到了不少用户的偏爱,但流畅只是一方面, Chrome 最大的优势还是其支持众多强大好用的扩展程序(E...

3.6K4
来自专栏逸鹏说道

一个粗心的Bug,JSON格式不规范导致AJAX错误

一、事件回放 今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里。 当时正在联调一个项目,由于后端没有提供数据...

3634
来自专栏大数据挖掘DT机器学习

QQ空间(日志、说说、个人信息)python爬虫源码(一天可抓取 400 万条数据)

爬虫功能: QQSpider 使用广度优先策略爬取QQ空间中的个人信息、日志、说说、好友四个方面的信息。 判重使用“内存位”判重,理论上亿数量级的QQ可瞬间判...

6044
来自专栏Web项目聚集地

我珍藏的神兵利器(软件篇)

快速启动应用+文件搜索+各种实用插件(计算器、翻译、网页快速访问等)。我的最爱,没有它我几乎半残。

4064
来自专栏速成应用小程序

小程序注册开发制作过程中要注意哪些?

小程序在注册制作发布过程中常常会遇见审核不通过或是上线后被停止等问题,那么怎么避免这类问题的出现呢?

5007
来自专栏阮一峰的网络日志

Usenet:P2P下载的替代方法

在上一篇网志中,我已经说了,我打算好好研究和介绍usenet。 下面就是我翻译的第一篇教程。它的信息量很大,非常通俗实用。基本上,读完这篇文章,你就会使用use...

4308
来自专栏零基础使用Django2.0.1打造在线教育网站

零基础使用Django2.0.1打造在线教育网站(二十一):讲师相关页面配置

努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

1922
来自专栏iOS技术

设计一个简单的 iOS 架构前言一、关于组件化二、模块化思维划分文件三、减少全局宏的使用四、去基类化设计五、MVC?MVP?MVVM?VIPER?结语

正如“100个读者就有100个哈姆雷特”一样,对于架构的理解不同的软件工程师有不同的看法。架构设计往往是一个权衡的过程,每一个架构设计者都要考虑到各个因素,比如...

1683
来自专栏腾讯Bugly的专栏

《客厅TV-APP首页瀑布流后台猫腻细窥》

1、项目概况 横版式已经持续使用了约2年,内容排布、主题细分、露出效率、操作便利等方面都有一些不足。而瀑布流则能很好的解决这些不足,在业界已经是一种通用的做法。...

52510

扫码关注云+社区

领取腾讯云代金券