PageRenderTime 47ms CodeModel.GetById 21ms app.highlight 21ms RepoModel.GetById 2ms app.codeStats 0ms

/wordpress/wp-content/plugins/wp-multibyte-patch/wp-multibyte-patch.php

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