PluginProbe ʕ •ᴥ•ʔ
WP Multibyte Patch / 1.5
WP Multibyte Patch v1.5
trunk 1.4.2 1.5 1.5.1 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.7 1.8 1.9 2.0 2.1.1 2.2 2.3 2.3.1 2.4 2.5 2.6 2.7 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.9 2.9.1 2.9.2 2.9.3
wp-multibyte-patch / wp-multibyte-patch.php
wp-multibyte-patch Last commit date
ext 14 years ago languages 14 years ago readme.txt 14 years ago wp-multibyte-patch.php 14 years ago wpmp-config-sample.php 14 years ago wpmp-load.php 14 years ago
wp-multibyte-patch.php
443 lines
1 <?php
2 /*
3 Plugin Name: WP Multibyte Patch
4 Plugin URI: http://eastcoder.com/code/wp-multibyte-patch/
5 Description: Enhances multibyte string I/O functionality of WordPress.
6 Author: Kuraishi (tenpura)
7 Version: 1.5
8 Author URI: http://eastcoder.com/
9 Text Domain: wp-multibyte-patch
10 Domain Path: /languages
11 */
12
13 /*
14 Copyright (C) 2011 Kuraishi (Email: 210pura at gmail dot com), Tinybit Inc.
15 This program is licensed under the GNU GPL Version 2.
16 */
17
18 class multibyte_patch {
19
20 // Do not edit this section. Use wpmp-config.php instead.
21
22 var $conf = array(
23 'excerpt_length' => 55,
24 'excerpt_mblength' => 110,
25 'excerpt_more' => ' [...]',
26 'comment_excerpt_length' => 20,
27 'comment_excerpt_mblength' => 40,
28 'ascii_threshold' => 90,
29 'patch_wp_mail' => true,
30 'patch_incoming_trackback' => true,
31 'patch_incoming_pingback' => true,
32 'patch_wp_trim_excerpt' => true,
33 'patch_get_comment_excerpt' => true,
34 'patch_process_search_terms' => true,
35 'patch_admin_custom_css' => true,
36 'patch_wplink_js' => true,
37 'patch_word_count_js' => true,
38 'patch_sanitize_file_name' => true,
39 'patch_bp_create_excerpt' => false,
40 'bp_excerpt_mblength' => 110,
41 'bp_excerpt_more' => ' [...]'
42 );
43
44 var $blog_encoding;
45 var $has_mbfunctions;
46 var $textdomain = 'wp-multibyte-patch';
47 var $lang_dir = 'languages';
48 var $required_version = '3.2';
49 var $query_based_vars = array();
50
51 function guess_encoding($string, $encoding = '') {
52 $blog_encoding = $this->blog_encoding;
53
54 if(!$encoding && seems_utf8($string))
55 return 'UTF-8';
56 elseif(!$encoding)
57 return $blog_encoding;
58 else
59 return $encoding;
60 }
61
62 function convenc($string, $to_encoding, $from_encoding = '') {
63 $blog_encoding = $this->blog_encoding;
64
65 if('' == $from_encoding)
66 $from_encoding = $blog_encoding;
67
68 if(strtoupper($to_encoding) == strtoupper($from_encoding))
69 return $string;
70 else
71 return mb_convert_encoding($string, $to_encoding, $from_encoding);
72 }
73
74 function incoming_trackback($commentdata) {
75 global $wpdb;
76
77 if('trackback' != $commentdata['comment_type'])
78 return $commentdata;
79
80 if(false === $this->conf['patch_incoming_trackback'])
81 return $commentdata;
82
83 $title = isset($_POST['title']) ? stripslashes($_POST['title']) : '';
84 $excerpt = isset($_POST['excerpt']) ? stripslashes($_POST['excerpt']) : '';
85 $blog_name = isset($_POST['blog_name']) ? stripslashes($_POST['blog_name']) : '';
86 $blog_encoding = $this->blog_encoding;
87
88 $from_encoding = isset($_POST['charset']) ? $_POST['charset'] : '';
89
90 if(!$from_encoding)
91 $from_encoding = (preg_match("/^.*charset=([a-zA-Z0-9\-_]+).*$/i", $_SERVER['CONTENT_TYPE'], $matched)) ? $matched[1] : '';
92
93 $from_encoding = str_replace(array(',', ' '), '', strtoupper(trim($from_encoding)));
94 $from_encoding = $this->guess_encoding($excerpt . $title . $blog_name, $from_encoding);
95
96 $title = $this->convenc($title, $blog_encoding, $from_encoding);
97 $blog_name = $this->convenc($blog_name, $blog_encoding, $from_encoding);
98 $excerpt = $this->convenc($excerpt, $blog_encoding, $from_encoding);
99
100 $title = strip_tags($title);
101 $excerpt = strip_tags($excerpt);
102
103 $title = (strlen($title) > 250) ? mb_strcut($title, 0, 250, $blog_encoding) . '...' : $title;
104 $excerpt = (strlen($excerpt) > 255) ? mb_strcut($excerpt, 0, 252, $blog_encoding) . '...' : $excerpt;
105
106 $commentdata['comment_author'] = $wpdb->escape($blog_name);
107 $commentdata['comment_content'] = $wpdb->escape("<strong>$title</strong>\n\n$excerpt");
108
109 return $commentdata;
110 }
111
112 function pre_remote_source($linea, $pagelinkedto) {
113 $this->pingback_ping_linea = $linea;
114 $this->pingback_ping_pagelinkedto = $pagelinkedto;
115 return $linea;
116 }
117
118 function incoming_pingback($commentdata) {
119 if('pingback' != $commentdata['comment_type'])
120 return $commentdata;
121
122 if(false === $this->conf['patch_incoming_pingback'])
123 return $commentdata;
124
125 $pagelinkedto = $this->pingback_ping_pagelinkedto;
126 $linea = $this->pingback_ping_linea;
127
128 $linea = preg_replace("/" . preg_quote('<!DOC', '/') . "/i", '<DOC', $linea);
129 $linea = preg_replace("/[\r\n\t ]+/", ' ', $linea);
130 $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);
131
132 preg_match("/<meta[^<>]+charset=\"*([a-zA-Z0-9\-_]+)\"*[^<>]*>/i", $linea, $matches);
133 $charset = isset($matches[1]) ? $matches[1] : '';
134 $from_encoding = $this->guess_encoding(strip_tags($linea), $charset);
135 $blog_encoding = $this->blog_encoding;
136
137 $linea = strip_tags($linea, '<a>');
138 $linea = $this->convenc($linea, $blog_encoding, $from_encoding);
139 $p = explode("\n\n", $linea);
140
141 foreach ($p as $para) {
142 if(strpos($para, $pagelinkedto) !== false && preg_match("/^([^<>]*)(\<a[^<>]+[\"']" . preg_quote($pagelinkedto, '/') . "[\"'][^<>]*\>)([^<>]+)(\<\/a\>)(.*)$/i", $para, $context))
143 break;
144 }
145
146 if(!$context)
147 return $commentdata;
148
149 $context[1] = strip_tags($context[1]);
150 $context[5] = strip_tags($context[5]);
151 $len_max = 250;
152 $len_c3 = strlen($context[3]);
153
154 if($len_c3 > $len_max) {
155 $excerpt = mb_strcut($context[3], 0, 250, $blog_encoding);
156 } else {
157 $len_c1 = strlen($context[1]);
158 $len_c5 = strlen($context[5]);
159 $len_left = $len_max - $len_c3;
160 $len_left_even = ceil($len_left / 2);
161
162 if($len_left_even > $len_c1) {
163 $context[5] = mb_strcut($context[5], 0, $len_left - $len_c1, $blog_encoding);
164 }
165 elseif($len_left_even > $len_c5) {
166 $context[1] .= "\t\t\t\t\t\t";
167 $context[1] = mb_strcut($context[1], $len_c1 - ($len_left - $len_c5), $len_c1 + 6, $blog_encoding);
168 $context[1] = preg_replace("/\t*$/", '', $context[1]);
169 }
170 else {
171 $context[1] .= "\t\t\t\t\t\t";
172 $context[1] = mb_strcut($context[1], $len_c1 - $len_left_even, $len_c1 + 6, $blog_encoding);
173 $context[1] = preg_replace("/\t*$/", '', $context[1]);
174 $context[5] = mb_strcut($context[5], 0, $len_left_even, $blog_encoding);
175 }
176
177 $excerpt = $context[1] . $context[3] . $context[5];
178 }
179
180 $commentdata['comment_content'] = '[...] ' . esc_html($excerpt) . ' [...]';
181 $commentdata['comment_content'] = addslashes($commentdata['comment_content']);
182 $commentdata['comment_author'] = stripslashes($commentdata['comment_author']);
183 $commentdata['comment_author'] = $this->convenc($commentdata['comment_author'], $blog_encoding, $from_encoding);
184 $commentdata['comment_author'] = addslashes($commentdata['comment_author']);
185
186 return $commentdata;
187 }
188
189 function preprocess_comment($commentdata) {
190 if($commentdata['comment_type'] == 'trackback')
191 return $this->incoming_trackback($commentdata);
192 elseif($commentdata['comment_type'] == 'pingback')
193 return $this->incoming_pingback($commentdata);
194 else
195 return $commentdata;
196 }
197
198 function is_almost_ascii($string, $encoding) {
199 if(100 === $this->conf['ascii_threshold'])
200 return false;
201
202 return ($this->conf['ascii_threshold'] < round(@(mb_strlen($string, $encoding) / strlen($string)) * 100)) ? true : false;
203 }
204
205 function wp_trim_excerpt($text) {
206 $raw_excerpt = $text;
207
208 $blog_encoding = $this->blog_encoding;
209
210 if('' == $text) {
211 $text = get_the_content('');
212
213 $text = strip_shortcodes( $text );
214
215 $text = apply_filters('the_content', $text);
216 $text = str_replace(']]>', ']]&gt;', $text);
217 $text = strip_tags($text);
218 $excerpt_length = apply_filters('excerpt_length', $this->conf['excerpt_length']);
219 $excerpt_mblength = apply_filters('excerpt_mblength', $this->conf['excerpt_mblength']);
220 $excerpt_more = apply_filters('excerpt_more', $this->conf['excerpt_more']);
221
222 if($this->is_almost_ascii($text, $blog_encoding)) {
223 $words = preg_split("/[\n\r\t ]+/", $text, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
224
225 if ( count($words) > $excerpt_length ) {
226 array_pop($words);
227 $text = implode(' ', $words);
228 $text = $text . $excerpt_more;
229 } else {
230 $text = implode(' ', $words);
231 }
232 }
233 else {
234 $text = trim(preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');
235
236 if(mb_strlen($text, $blog_encoding) > $excerpt_mblength)
237 $text = mb_substr($text, 0, $excerpt_mblength, $blog_encoding) . $excerpt_more;
238 }
239 }
240
241 return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
242 }
243
244 function trim_multibyte_excerpt($text = '', $length = 110, $more = ' [...]', $encoding = 'UTF-8') {
245 $text = strip_shortcodes($text);
246 $text = str_replace(']]>', ']]&gt;', $text);
247 $text = strip_tags($text);
248 $text = trim(preg_replace("/[\n\r\t ]+/", ' ', $text), ' ');
249
250 if(mb_strlen($text, $encoding) > $length)
251 $text = mb_substr($text, 0, $length, $encoding) . $more;
252
253 return $text;
254 }
255
256 function bp_create_excerpt($text = '') {
257 if($this->is_almost_ascii($text, $this->blog_encoding))
258 return $text;
259 else
260 return $this->trim_multibyte_excerpt($text, $this->conf['bp_excerpt_mblength'], $this->conf['bp_excerpt_more'], $this->blog_encoding);
261 }
262
263 function bp_get_activity_content_body($content = '') {
264 return preg_replace("/<a [^<>]+>([^<>]+)<\/a>(" . preg_quote($this->conf['bp_excerpt_more'], '/') . "<\/p>)$/", "$1$2", $content);
265 }
266
267 // param $excerpt could already be truncated to 20 words or less by the original get_comment_excerpt() function.
268 function get_comment_excerpt($excerpt = '') {
269 $excerpt = preg_replace("/\.\.\.$/", '', $excerpt);
270 $blog_encoding = $this->blog_encoding;
271
272 if($this->is_almost_ascii($excerpt, $blog_encoding)) {
273 $words = explode(' ', $excerpt, $this->conf['comment_excerpt_length'] + 1);
274
275 if(count($words) > $this->conf['comment_excerpt_length']) {
276 array_pop($words);
277 $excerpt = implode(' ', $words) . '...';
278 }
279 }
280 elseif(mb_strlen($excerpt, $blog_encoding) > $this->conf['comment_excerpt_mblength']) {
281 $excerpt = mb_substr($excerpt, 0, $this->conf['comment_excerpt_mblength'], $blog_encoding) . '...';
282 }
283
284 return $excerpt;
285 }
286
287 function sanitize_file_name($name) {
288 $info = pathinfo($name);
289 $ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
290 $name = str_replace($ext, '', $name);
291 $name_enc = rawurlencode($name);
292 $name = ($name == $name_enc) ? $name . $ext : md5($name) . $ext;
293 return $name;
294 }
295
296 function excerpt_mblength($length) {
297 if(isset($this->query_based_vars['excerpt_mblength']) && (int) $this->query_based_vars['excerpt_mblength'])
298 return $this->query_based_vars['excerpt_mblength'];
299 else
300 return (int) $length;
301 }
302
303 function excerpt_more($more) {
304 if(isset($this->query_based_vars['excerpt_more']))
305 return $this->query_based_vars['excerpt_more'];
306 else
307 return $more;
308 }
309
310 function query_based_settings() {
311 $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');
312
313 foreach($is_query_funcs as $func) {
314 if(isset($this->conf['excerpt_mblength.' . $func]) && !isset($this->query_based_vars['excerpt_mblength']) && $func())
315 $this->query_based_vars['excerpt_mblength'] = $this->conf['excerpt_mblength.' . $func];
316
317 if(isset($this->conf['excerpt_more.' . $func]) && !isset($this->query_based_vars['excerpt_more']) && $func())
318 $this->query_based_vars['excerpt_more'] = $this->conf['excerpt_more.' . $func];
319 }
320 }
321
322 function import_l10n_entry($text, $from_domain, $to_domain = 'default') {
323 global $l10n;
324
325 if(isset($l10n[$to_domain]->entries) && isset($l10n[$from_domain]->entries[$text]))
326 $l10n[$to_domain]->entries[$text] = $l10n[$from_domain]->entries[$text];
327 }
328
329 function filters() {
330 // remove filter
331 if(false !== $this->conf['patch_wp_trim_excerpt'])
332 remove_filter('get_the_excerpt', 'wp_trim_excerpt');
333
334 // add filter
335 add_filter('preprocess_comment', array(&$this, 'preprocess_comment'), 99);
336 add_filter('excerpt_mblength', array(&$this, 'excerpt_mblength'), 9);
337 add_filter('excerpt_more', array(&$this, 'excerpt_more'), 9);
338
339 if(false !== $this->conf['patch_incoming_pingback'])
340 add_filter('pre_remote_source', array(&$this, 'pre_remote_source'), 10, 2);
341
342 if(false !== $this->conf['patch_wp_trim_excerpt'])
343 add_filter('get_the_excerpt', array(&$this, 'wp_trim_excerpt'));
344
345 if(false !== $this->conf['patch_get_comment_excerpt'])
346 add_filter('get_comment_excerpt', array(&$this, 'get_comment_excerpt'));
347
348 if(false !== $this->conf['patch_sanitize_file_name'])
349 add_filter('sanitize_file_name', array(&$this, 'sanitize_file_name'));
350
351 if(false !== $this->conf['patch_bp_create_excerpt']) {
352 add_filter('bp_create_excerpt', array(&$this, 'bp_create_excerpt'), 99);
353 add_filter('bp_get_activity_content_body', array(&$this, 'bp_get_activity_content_body'), 99);
354 }
355
356 // add action
357 add_action('wp', array(&$this, 'query_based_settings'));
358
359 if(method_exists($this, 'process_search_terms') && false !== $this->conf['patch_process_search_terms'])
360 add_action('sanitize_comment_cookies', array(&$this, 'process_search_terms'));
361
362 if(method_exists($this, 'wp_mail') && false !== $this->conf['patch_wp_mail'])
363 add_action('phpmailer_init', array(&$this, 'wp_mail'));
364
365 if(method_exists($this, 'admin_custom_css') && false !== $this->conf['patch_admin_custom_css'])
366 add_action('admin_head' , array(&$this, 'admin_custom_css'), 99);
367
368 if(method_exists($this, 'wplink_js') && false !== $this->conf['patch_wplink_js'])
369 add_action('wp_default_scripts' , array(&$this, 'wplink_js'), 9);
370
371 if(method_exists($this, 'word_count_js') && false !== $this->conf['patch_word_count_js'])
372 add_action('wp_default_scripts' , array(&$this, 'word_count_js'), 9);
373 }
374
375 function mbfunctions_exist() {
376 return (
377 function_exists('mb_convert_encoding') &&
378 function_exists('mb_convert_kana') &&
379 function_exists('mb_detect_encoding') &&
380 function_exists('mb_strcut') &&
381 function_exists('mb_strlen') &&
382 function_exists('mb_substr')
383 ) ? true : false;
384 }
385
386 function activation_check() {
387 global $wp_version;
388 $required_version = $this->required_version;
389
390 if(version_compare(substr($wp_version, 0, strlen($required_version)), $required_version, '<')) {
391 deactivate_plugins(__FILE__);
392 wp_die(sprintf(__('Sorry, WP Multibyte Patch requires WordPress %s or later.', 'wp-multibyte-patch'), $required_version));
393 }
394 elseif(!$this->has_mbfunctions) {
395 deactivate_plugins(__FILE__);
396 wp_die(__('Sorry, WP Multibyte Patch requires mbstring functions.', 'wp-multibyte-patch'));
397 }
398 }
399
400 function load_conf() {
401 $wpmp_conf = array();
402
403 if(file_exists(WP_CONTENT_DIR . '/wpmp-config.php'))
404 require_once(WP_CONTENT_DIR . '/wpmp-config.php');
405
406 if(is_multisite()) {
407 $blog_id = get_current_blog_id();
408 if(file_exists(WP_CONTENT_DIR . '/wpmp-config-blog-' . $blog_id . '.php'))
409 require_once(WP_CONTENT_DIR . '/wpmp-config-blog-' . $blog_id . '.php');
410 }
411
412 $this->conf = array_merge($this->conf, $wpmp_conf);
413 }
414
415 function __construct() {
416 $this->load_conf();
417
418 $this->blog_encoding = get_option('blog_charset');
419 $this->has_mbfunctions = $this->mbfunctions_exist();
420
421 load_textdomain($this->textdomain, plugin_dir_path(__FILE__) . $this->lang_dir . '/' . $this->textdomain . '-' . get_locale() . '.mo');
422 register_activation_hook(__FILE__, array(&$this, 'activation_check'));
423
424 $this->filters();
425 }
426 }
427
428 if(defined('WP_PLUGIN_URL')) {
429 global $wpmp;
430
431 if(file_exists(dirname(__FILE__) . '/ext/' . get_locale() . '/class.php')) {
432 require_once(dirname(__FILE__) . '/ext/' . get_locale() . '/class.php');
433 $wpmp = new multibyte_patch_ext();
434 }
435 elseif(file_exists(dirname(__FILE__) . '/ext/default/class.php')) {
436 require_once(dirname(__FILE__) . '/ext/default/class.php');
437 $wpmp = new multibyte_patch_ext();
438 }
439 else
440 $wpmp = new multibyte_patch();
441 }
442
443 ?>