PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/wordpress3.4.2/wp-content/plugins/wp-multibyte-patch/wp-multibyte-patch.php

https://bitbucket.org/ch3tag/mothers
PHP | 480 lines | 412 code | 40 blank | 28 comment | 22 complexity | addaf485051192b15e1cc773461a2c78 MD5 | raw file
  1. <?php
  2. /*
  3. Plugin Name: WP Multibyte Patch
  4. Description: Multibyte functionality enhancement for the WordPress Japanese package.
  5. Version: 1.6.3
  6. Plugin URI: http://eastcoder.com/code/wp-multibyte-patch/
  7. Author: Seisuke Kuraishi
  8. Author URI: http://tinybit.co.jp/
  9. License: GPLv2
  10. Text Domain: wp-multibyte-patch
  11. Domain Path: /languages
  12. */
  13. /**
  14. * Multibyte functionality enhancement for the WordPress Japanese package.
  15. *
  16. * @package WP_Multibyte_Patch
  17. * @version 1.6.3
  18. * @author Seisuke Kuraishi <210pura@gmail.com>
  19. * @copyright Copyright (c) 2012 Seisuke Kuraishi, Tinybit Inc.
  20. * @license http://opensource.org/licenses/gpl-2.0.php GPLv2
  21. * @link http://eastcoder.com/code/wp-multibyte-patch/
  22. */
  23. /**
  24. * @package WP_Multibyte_Patch
  25. */
  26. class multibyte_patch {
  27. // Do not edit this section. Use wpmp-config.php instead.
  28. var $conf = array(
  29. 'excerpt_mblength' => 110,
  30. 'excerpt_more' => ' [...]',
  31. 'comment_excerpt_mblength' => 40,
  32. 'dashboard_recent_drafts_mblength' => 40,
  33. 'patch_wp_mail' => false,
  34. 'patch_incoming_trackback' => false,
  35. 'patch_incoming_pingback' => false,
  36. 'patch_wp_trim_excerpt' => true,
  37. 'patch_wp_trim_words' => false,
  38. 'patch_get_comment_excerpt' => true,
  39. 'patch_dashboard_recent_drafts' => true,
  40. 'patch_process_search_terms' => false,
  41. 'patch_admin_custom_css' => false,
  42. 'patch_wplink_js' => true,
  43. 'patch_word_count_js' => true,
  44. 'patch_force_character_count' => false,
  45. 'patch_force_twentytwelve_open_sans_off' => false,
  46. 'patch_sanitize_file_name' => true,
  47. 'patch_bp_create_excerpt' => false,
  48. 'bp_excerpt_mblength' => 110,
  49. 'bp_excerpt_more' => ' [...]'
  50. );
  51. var $blog_encoding = 'UTF-8';
  52. var $has_mbfunctions = false;
  53. var $mbfunctions_required = false;
  54. var $has_mb_strlen = false;
  55. var $debug_suffix = '';
  56. var $textdomain = 'wp-multibyte-patch';
  57. var $lang_dir = 'languages';
  58. var $required_version = '3.4-RC2';
  59. var $query_based_vars = array();
  60. // For fallback purpose only. (1.6)
  61. function guess_encoding($string, $encoding = '') {
  62. $blog_encoding = $this->blog_encoding;
  63. if(!$encoding && seems_utf8($string))
  64. return 'UTF-8';
  65. elseif(!$encoding)
  66. return $blog_encoding;
  67. else
  68. return $encoding;
  69. }
  70. // For fallback purpose only. (1.6)
  71. function convenc($string, $to_encoding, $from_encoding = '') {
  72. $blog_encoding = $this->blog_encoding;
  73. if('' == $from_encoding)
  74. $from_encoding = $blog_encoding;
  75. if(strtoupper($to_encoding) == strtoupper($from_encoding))
  76. return $string;
  77. else
  78. return mb_convert_encoding($string, $to_encoding, $from_encoding);
  79. }
  80. function incoming_trackback($commentdata) {
  81. global $wpdb;
  82. if('trackback' != $commentdata['comment_type'])
  83. return $commentdata;
  84. if(false === $this->conf['patch_incoming_trackback'])
  85. return $commentdata;
  86. $title = isset($_POST['title']) ? stripslashes($_POST['title']) : '';
  87. $excerpt = isset($_POST['excerpt']) ? stripslashes($_POST['excerpt']) : '';
  88. $blog_name = isset($_POST['blog_name']) ? stripslashes($_POST['blog_name']) : '';
  89. $blog_encoding = $this->blog_encoding;
  90. $from_encoding = isset($_POST['charset']) ? $_POST['charset'] : '';
  91. if(!$from_encoding)
  92. $from_encoding = (preg_match("/^.*charset=([a-zA-Z0-9\-_]+).*$/i", $_SERVER['CONTENT_TYPE'], $matched)) ? $matched[1] : '';
  93. $from_encoding = str_replace(array(',', ' '), '', strtoupper(trim($from_encoding)));
  94. $from_encoding = $this->guess_encoding($excerpt . $title . $blog_name, $from_encoding);
  95. $title = $this->convenc($title, $blog_encoding, $from_encoding);
  96. $blog_name = $this->convenc($blog_name, $blog_encoding, $from_encoding);
  97. $excerpt = $this->convenc($excerpt, $blog_encoding, $from_encoding);
  98. $title = strip_tags($title);
  99. $excerpt = strip_tags($excerpt);
  100. $title = (strlen($title) > 250) ? mb_strcut($title, 0, 250, $blog_encoding) . '...' : $title;
  101. $excerpt = (strlen($excerpt) > 255) ? mb_strcut($excerpt, 0, 252, $blog_encoding) . '...' : $excerpt;
  102. $commentdata['comment_author'] = $wpdb->escape($blog_name);
  103. $commentdata['comment_content'] = $wpdb->escape("<strong>$title</strong>\n\n$excerpt");
  104. return $commentdata;
  105. }
  106. function pre_remote_source($linea, $pagelinkedto) {
  107. $this->pingback_ping_linea = $linea;
  108. $this->pingback_ping_pagelinkedto = $pagelinkedto;
  109. return $linea;
  110. }
  111. function incoming_pingback($commentdata) {
  112. if('pingback' != $commentdata['comment_type'])
  113. return $commentdata;
  114. if(false === $this->conf['patch_incoming_pingback'])
  115. return $commentdata;
  116. $pagelinkedto = $this->pingback_ping_pagelinkedto;
  117. $linea = $this->pingback_ping_linea;
  118. $linea = preg_replace("/" . preg_quote('<!DOC', '/') . "/i", '<DOC', $linea);
  119. $linea = preg_replace("/[\r\n\t ]+/", ' ', $linea);
  120. $linea = preg_replace("/ <(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/i", "\n\n", $linea);
  121. preg_match("/<meta[^<>]+charset=\"*([a-zA-Z0-9\-_]+)\"*[^<>]*>/i", $linea, $matches);
  122. $charset = isset($matches[1]) ? $matches[1] : '';
  123. $from_encoding = $this->guess_encoding(strip_tags($linea), $charset);
  124. $blog_encoding = $this->blog_encoding;
  125. $linea = strip_tags($linea, '<a>');
  126. $linea = $this->convenc($linea, $blog_encoding, $from_encoding);
  127. $p = explode("\n\n", $linea);
  128. foreach ($p as $para) {
  129. if(strpos($para, $pagelinkedto) !== false && preg_match("/^([^<>]*)(\<a[^<>]+[\"']" . preg_quote($pagelinkedto, '/') . "[\"'][^<>]*\>)([^<>]+)(\<\/a\>)(.*)$/i", $para, $context))
  130. break;
  131. }
  132. if(!$context)
  133. return $commentdata;
  134. $context[1] = strip_tags($context[1]);
  135. $context[5] = strip_tags($context[5]);
  136. $len_max = 250;
  137. $len_c3 = strlen($context[3]);
  138. if($len_c3 > $len_max) {
  139. $excerpt = mb_strcut($context[3], 0, 250, $blog_encoding);
  140. } else {
  141. $len_c1 = strlen($context[1]);
  142. $len_c5 = strlen($context[5]);
  143. $len_left = $len_max - $len_c3;
  144. $len_left_even = ceil($len_left / 2);
  145. if($len_left_even > $len_c1) {
  146. $context[5] = mb_strcut($context[5], 0, $len_left - $len_c1, $blog_encoding);
  147. }
  148. elseif($len_left_even > $len_c5) {
  149. $context[1] .= "\t\t\t\t\t\t";
  150. $context[1] = mb_strcut($context[1], $len_c1 - ($len_left - $len_c5), $len_c1 + 6, $blog_encoding);
  151. $context[1] = preg_replace("/\t*$/", '', $context[1]);
  152. }
  153. else {
  154. $context[1] .= "\t\t\t\t\t\t";
  155. $context[1] = mb_strcut($context[1], $len_c1 - $len_left_even, $len_c1 + 6, $blog_encoding);
  156. $context[1] = preg_replace("/\t*$/", '', $context[1]);
  157. $context[5] = mb_strcut($context[5], 0, $len_left_even, $blog_encoding);
  158. }
  159. $excerpt = $context[1] . $context[3] . $context[5];
  160. }
  161. $commentdata['comment_content'] = '[...] ' . esc_html($excerpt) . ' [...]';
  162. $commentdata['comment_content'] = addslashes($commentdata['comment_content']);
  163. $commentdata['comment_author'] = stripslashes($commentdata['comment_author']);
  164. $commentdata['comment_author'] = $this->convenc($commentdata['comment_author'], $blog_encoding, $from_encoding);
  165. $commentdata['comment_author'] = addslashes($commentdata['comment_author']);
  166. return $commentdata;
  167. }
  168. function preprocess_comment($commentdata) {
  169. if($commentdata['comment_type'] == 'trackback')
  170. return $this->incoming_trackback($commentdata);
  171. elseif($commentdata['comment_type'] == 'pingback')
  172. return $this->incoming_pingback($commentdata);
  173. else
  174. return $commentdata;
  175. }
  176. function trim_multibyte_excerpt($text = '', $length = 110, $more = ' [...]', $encoding = 'UTF-8') {
  177. $text = strip_shortcodes($text);
  178. $text = str_replace(']]>', ']]&gt;', $text);
  179. $text = strip_tags($text);
  180. $text = trim(preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');
  181. if($this->mb_strlen($text, $encoding) > $length)
  182. $text = mb_substr($text, 0, $length, $encoding) . $more;
  183. return $text;
  184. }
  185. function bp_create_excerpt($text = '') {
  186. return $this->trim_multibyte_excerpt($text, $this->conf['bp_excerpt_mblength'], $this->conf['bp_excerpt_more'], $this->blog_encoding);
  187. }
  188. function bp_get_activity_content_body($content = '') {
  189. return preg_replace("/<a [^<>]+>([^<>]+)<\/a>(" . preg_quote($this->conf['bp_excerpt_more'], '/') . "<\/p>)$/", "$1$2", $content);
  190. }
  191. // param $excerpt could already be truncated to 20 words or less by the original get_comment_excerpt() function.
  192. function get_comment_excerpt($excerpt = '') {
  193. $excerpt = preg_replace("/\.\.\.$/", '', $excerpt);
  194. $blog_encoding = $this->blog_encoding;
  195. if($this->mb_strlen($excerpt, $blog_encoding) > $this->conf['comment_excerpt_mblength'])
  196. $excerpt = mb_substr($excerpt, 0, $this->conf['comment_excerpt_mblength'], $blog_encoding) . '...';
  197. return $excerpt;
  198. }
  199. function excerpt_mblength() {
  200. if(isset($this->query_based_vars['excerpt_mblength']) && (int) $this->query_based_vars['excerpt_mblength'])
  201. $length = (int) $this->query_based_vars['excerpt_mblength'];
  202. else
  203. $length = (int) $this->conf['excerpt_mblength'];
  204. return apply_filters('excerpt_mblength', $length);
  205. }
  206. function excerpt_more() {
  207. if(isset($this->query_based_vars['excerpt_more']))
  208. return $this->query_based_vars['excerpt_more'];
  209. else
  210. return $this->conf['excerpt_more'];
  211. }
  212. function sanitize_file_name($name) {
  213. $info = pathinfo($name);
  214. $ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
  215. $name = str_replace($ext, '', $name);
  216. $name_enc = rawurlencode($name);
  217. $name = ($name == $name_enc) ? $name . $ext : md5($name) . $ext;
  218. return $name;
  219. }
  220. function wplink_js(&$scripts) {
  221. $scripts->add('wplink', plugin_dir_url(__FILE__) . "js/wplink{$this->debug_suffix}.js", array('jquery', 'wpdialogs'), false, 1 );
  222. }
  223. function word_count_js(&$scripts) {
  224. $scripts->add('word-count', plugin_dir_url(__FILE__) . "js/word-count{$this->debug_suffix}.js", array('jquery'), false, 1);
  225. }
  226. function force_character_count($translations = '', $text = '', $context = '') {
  227. if('word count: words or characters?' == $context && 'words' == $text)
  228. return 'characters';
  229. return $translations;
  230. }
  231. function force_twentytwelve_open_sans_off() {
  232. wp_dequeue_style('twentytwelve-fonts');
  233. }
  234. function wp_dashboard_recent_drafts( $drafts = false ) {
  235. if ( !$drafts ) {
  236. $drafts_query = new WP_Query( array(
  237. 'post_type' => 'post',
  238. 'post_status' => 'draft',
  239. 'author' => $GLOBALS['current_user']->ID,
  240. 'posts_per_page' => 5,
  241. 'orderby' => 'modified',
  242. 'order' => 'DESC'
  243. ) );
  244. $drafts =& $drafts_query->posts;
  245. }
  246. if ( $drafts && is_array( $drafts ) ) {
  247. $list = array();
  248. foreach ( $drafts as $draft ) {
  249. $url = get_edit_post_link( $draft->ID );
  250. $title = _draft_or_post_title( $draft->ID );
  251. $item = "<h4><a href='$url' title='" . sprintf( __( 'Edit &#8220;%s&#8221;' ), esc_attr( $title ) ) . "'>" . esc_html($title) . "</a> <abbr title='" . get_the_time(__('Y/m/d g:i:s A'), $draft) . "'>" . get_the_time( get_option( 'date_format' ), $draft ) . '</abbr></h4>';
  252. $item .= '<p>' . $this->trim_multibyte_excerpt($draft->post_content, $this->conf['dashboard_recent_drafts_mblength'], $more = '&hellip;', $this->blog_encoding) . '</p>';
  253. $list[] = $item;
  254. }
  255. ?>
  256. <ul>
  257. <li><?php echo join( "</li>\n<li>", $list ); ?></li>
  258. </ul>
  259. <p class="textright"><a href="edit.php?post_status=draft" ><?php _e('View all'); ?></a></p>
  260. <?php
  261. } else {
  262. _e('There are no drafts at the moment');
  263. }
  264. }
  265. function dashboard_recent_drafts() {
  266. global $wp_meta_boxes;
  267. if(!empty($wp_meta_boxes['dashboard']['side']['core']['dashboard_recent_drafts']['callback']))
  268. $wp_meta_boxes['dashboard']['side']['core']['dashboard_recent_drafts']['callback'] = array($this, 'wp_dashboard_recent_drafts');
  269. }
  270. function query_based_settings() {
  271. $is_query_funcs = array('is_feed', 'is_404', 'is_search', 'is_tax', 'is_front_page', 'is_home', 'is_attachment', 'is_single', 'is_page', 'is_category', 'is_tag', 'is_author', 'is_date', 'is_archive', 'is_paged');
  272. foreach($is_query_funcs as $func) {
  273. if(isset($this->conf['excerpt_mblength.' . $func]) && !isset($this->query_based_vars['excerpt_mblength']) && $func())
  274. $this->query_based_vars['excerpt_mblength'] = $this->conf['excerpt_mblength.' . $func];
  275. if(isset($this->conf['excerpt_more.' . $func]) && !isset($this->query_based_vars['excerpt_more']) && $func())
  276. $this->query_based_vars['excerpt_more'] = $this->conf['excerpt_more.' . $func];
  277. }
  278. }
  279. // The fallback only works with UTF-8 blog.
  280. function mb_strlen($str = '', $encoding = 'UTF-8') {
  281. if($this->has_mb_strlen)
  282. return mb_strlen($str, $encoding);
  283. else
  284. return preg_match_all("/./us", $str, $match);
  285. }
  286. function filters_after_setup_theme() {
  287. // add filter
  288. if(false !== $this->conf['patch_force_character_count'] && 'characters' != _x('words', 'word count: words or characters?'))
  289. add_filter('gettext_with_context', array($this, 'force_character_count'), 10, 3);
  290. }
  291. function filters() {
  292. // add filter
  293. add_filter('preprocess_comment', array($this, 'preprocess_comment'), 99);
  294. if(false !== $this->conf['patch_incoming_pingback'])
  295. add_filter('pre_remote_source', array($this, 'pre_remote_source'), 10, 2);
  296. if(false !== $this->conf['patch_wp_trim_excerpt']) {
  297. add_filter('excerpt_length', array($this, 'excerpt_mblength'), 99);
  298. add_filter('excerpt_more', array($this, 'excerpt_more'), 9);
  299. }
  300. if(false !== $this->conf['patch_get_comment_excerpt'])
  301. add_filter('get_comment_excerpt', array($this, 'get_comment_excerpt'));
  302. if(false !== $this->conf['patch_sanitize_file_name'])
  303. add_filter('sanitize_file_name', array($this, 'sanitize_file_name'));
  304. if(false !== $this->conf['patch_bp_create_excerpt']) {
  305. add_filter('bp_create_excerpt', array($this, 'bp_create_excerpt'), 99);
  306. add_filter('bp_get_activity_content_body', array($this, 'bp_get_activity_content_body'), 99);
  307. }
  308. if(method_exists($this, 'wp_trim_words') && false !== $this->conf['patch_wp_trim_words'])
  309. add_filter('wp_trim_words', array($this, 'wp_trim_words'), 99, 4);
  310. // add action
  311. add_action('wp', array($this, 'query_based_settings'));
  312. if(method_exists($this, 'process_search_terms') && false !== $this->conf['patch_process_search_terms'])
  313. add_action('sanitize_comment_cookies', array($this, 'process_search_terms'));
  314. if(method_exists($this, 'wp_mail') && false !== $this->conf['patch_wp_mail'])
  315. add_action('phpmailer_init', array($this, 'wp_mail'));
  316. if(method_exists($this, 'admin_custom_css') && false !== $this->conf['patch_admin_custom_css']) {
  317. add_action('admin_enqueue_scripts', array($this, 'admin_custom_css'), 99);
  318. add_action('customize_controls_enqueue_scripts', array($this, 'admin_custom_css'), 99);
  319. }
  320. if(false !== $this->conf['patch_wplink_js'])
  321. add_action('wp_default_scripts', array($this, 'wplink_js'), 9);
  322. if(false !== $this->conf['patch_word_count_js'])
  323. add_action('wp_default_scripts', array($this, 'word_count_js'), 9);
  324. if(false !== $this->conf['patch_dashboard_recent_drafts'])
  325. add_action('wp_dashboard_setup', array($this, 'dashboard_recent_drafts'));
  326. if(false !== $this->conf['patch_force_twentytwelve_open_sans_off'] && 'twentytwelve' == get_template())
  327. add_action('wp_enqueue_scripts', array($this, 'force_twentytwelve_open_sans_off'), 99);
  328. add_action('after_setup_theme', array($this, 'filters_after_setup_theme'), 99);
  329. }
  330. function mbfunctions_exist() {
  331. return (
  332. function_exists('mb_convert_encoding') &&
  333. function_exists('mb_convert_kana') &&
  334. function_exists('mb_detect_encoding') &&
  335. function_exists('mb_strcut') &&
  336. function_exists('mb_strlen')
  337. ) ? true : false;
  338. }
  339. function activation_check() {
  340. global $wp_version;
  341. $required_version = $this->required_version;
  342. if(version_compare(substr($wp_version, 0, strlen($required_version)), $required_version, '<')) {
  343. deactivate_plugins(__FILE__);
  344. exit(sprintf(__('Sorry, WP Multibyte Patch requires WordPress %s or later.', 'wp-multibyte-patch'), $required_version));
  345. }
  346. elseif(!$this->has_mbfunctions && $this->mbfunctions_required) {
  347. deactivate_plugins(__FILE__);
  348. exit(__('Sorry, WP Multibyte Patch requires <a href="http://www.php.net/manual/en/mbstring.installation.php" target="_blank">mbstring</a> functions.', 'wp-multibyte-patch'));
  349. }
  350. }
  351. function load_conf() {
  352. $wpmp_conf = array();
  353. if(file_exists(WP_CONTENT_DIR . '/wpmp-config.php'))
  354. require_once(WP_CONTENT_DIR . '/wpmp-config.php');
  355. if(is_multisite()) {
  356. $blog_id = get_current_blog_id();
  357. if(file_exists(WP_CONTENT_DIR . '/wpmp-config-blog-' . $blog_id . '.php'))
  358. require_once(WP_CONTENT_DIR . '/wpmp-config-blog-' . $blog_id . '.php');
  359. }
  360. $this->conf = array_merge($this->conf, $wpmp_conf);
  361. }
  362. function __construct() {
  363. $this->load_conf();
  364. $this->blog_encoding = get_option('blog_charset');
  365. // mbstring functions are required for non UTF-8 blog.
  366. if(!preg_match("/^utf-?8$/i", $this->blog_encoding))
  367. $this->mbfunctions_required = true;
  368. $this->has_mbfunctions = $this->mbfunctions_exist();
  369. $this->has_mb_strlen = function_exists('mb_strlen');
  370. $this->debug_suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : '';
  371. load_textdomain($this->textdomain, plugin_dir_path(__FILE__) . $this->lang_dir . '/' . $this->textdomain . '-' . get_locale() . '.mo');
  372. register_activation_hook(__FILE__, array($this, 'activation_check'));
  373. $this->filters();
  374. }
  375. }
  376. if(defined('WP_PLUGIN_URL')) {
  377. global $wpmp;
  378. if(file_exists(dirname(__FILE__) . '/ext/' . get_locale() . '/class.php')) {
  379. require_once(dirname(__FILE__) . '/ext/' . get_locale() . '/class.php');
  380. $wpmp = new multibyte_patch_ext();
  381. }
  382. elseif(file_exists(dirname(__FILE__) . '/ext/default/class.php')) {
  383. require_once(dirname(__FILE__) . '/ext/default/class.php');
  384. $wpmp = new multibyte_patch_ext();
  385. }
  386. else
  387. $wpmp = new multibyte_patch();
  388. }
  389. ?>