// ----------------------------------------------------------
// PHẦN FRONTEND: Xử lý spin nội dung và các bộ lọc khác
// Thêm CSS tùy chỉnh cho các class spin
public function add_custom_styles() {
echo '';
}
// Lấy dữ liệu spin từ cache hoặc database
private function get_spin_data($category_id = 0) {
global $wpdb;
$cache_key = 'dataspin_' . $category_id;
$data = wp_cache_get($cache_key, 'dataspin');
if (false === $data) {
$data = $wpdb->get_row($wpdb->prepare(
"SELECT spin_level1, spin_level2 FROM {$this->table_name} WHERE category_id = %d LIMIT 1",
$category_id
), ARRAY_A);
if (!$data && $category_id != 0) {
// Fallback to global spin data if category-specific not found
$data = $wpdb->get_row(
"SELECT spin_level1, spin_level2 FROM {$this->table_name} WHERE category_id = 0 LIMIT 1",
ARRAY_A
);
}
$cache_duration = $this->get_cache_duration();
wp_cache_set($cache_key, $data, 'dataspin', $cache_duration);
}
return $data;
}
// Xử lý spin nội dung chính
public function spin_the_content($content) {
if (is_admin() || !is_singular() || post_password_required()) {
return $content;
}
$post = get_post();
$post_type = $post->post_type;
// Không xử lý spin cho blocks hoặc các post type đặc biệt
if ($post_type === 'blocks' || $post_type === 'revision') {
return $content;
}
// Lấy danh mục của bài viết
$categories = get_the_terms($post->ID, 'category');
$category_id = 0;
if ($categories && !is_wp_error($categories)) {
$primary_category = reset($categories);
$category_id = $primary_category->term_id;
}
// Lấy dữ liệu spin
$spin_data = $this->get_spin_data($category_id);
if (!$spin_data) {
return $content;
}
// Xử lý spin có sẵn trong nội dung trước
$content = $this->process_existing_spins($content);
// Áp dụng spin level 1
$spin_level1 = $spin_data['spin_level1'];
if (!empty($spin_level1)) {
$content = $this->apply_spin_level($content, $spin_level1, 'splv1');
}
// Áp dụng random spin (spin level 2) sau mỗi 40 ký tự không có spin
$spin_level2 = $spin_data['spin_level2'];
if (!empty($spin_level2)) {
$content = $this->apply_random_spins($content, $spin_level2, 'sprd');
}
return $content;
}
// Xử lý các spin có sẵn trong nội dung (dạng {a|b|c})
private function process_existing_spins($content) {
$pattern = '/\{([^{}]+)\}/';
return preg_replace_callback($pattern, function($matches) {
$options = explode('|', $matches[1]);
$selected = trim($options[array_rand($options)]);
return $selected;
}, $content);
}
// Áp dụng spin level (level1 hoặc level2) vào nội dung
private function apply_spin_level($content, $spin_text, $css_class) {
$spin_options = explode('|', $this->process_existing_spins($spin_text));
if (empty($spin_options)) {
return $content;
}
// Không xử lý trong các thẻ html đặc biệt
$exclude_tags = array('h1', 'h2', 'h3', 'h4', 'h5', 'a', 'img', 'strong', 'button');
$exclude_regex = '/<(' . implode('|', $exclude_tags) . ')[^>]*>.*?<\/\1>/is';
return preg_replace_callback($exclude_regex, function($matches) use ($spin_options, $css_class) {
// Bỏ qua nội dung trong các thẻ đặc biệt
return $matches[0];
}, $content, -1, $count);
// Áp dụng spin cho phần còn lại
$selected = trim($spin_options[array_rand($spin_options)]);
$selected = $this->capitalize_first_letter($selected);
// Chèn span với class tương ứng
$replacement = '' . esc_html($selected) . '';
// Tìm vị trí thích hợp để chèn (sau khoảng trắng)
$content = preg_replace('/(\s|^)([^\s<]+)(\s|$)/', '$1' . $replacement . '$3', $content);
return $content;
}
// Áp dụng random spin sau mỗi 40 ký tự không có spin
private function apply_random_spins($content, $spin_text, $css_class) {
$spin_options = explode('|', $this->process_existing_spins($spin_text));
if (empty($spin_options)) {
return $content;
}
// Tách nội dung thành các phần nhỏ để xử lý
$parts = preg_split('/(<[^>]+>)/', $content, -1, PREG_SPLIT_DELIM_CAPTURE);
$result = '';
$char_count = 0;
$spin_interval = 40; // Chèn sau mỗi 40 ký tự
foreach ($parts as $part) {
if (strpos($part, '<') === 0 && strpos($part, '>') !== false) {
// Đây là thẻ HTML, thêm vào kết quả không xử lý
$result .= $part;
continue;
}
$words = preg_split('/(\s+)/', $part, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($words as $word) {
if (trim($word) === '') {
$result .= $word;
continue;
}
$char_count += strlen($word);
$result .= $word;
if ($char_count >= $spin_interval) {
// Đã đủ 40 ký tự, chèn spin
$selected = trim($spin_options[array_rand($spin_options)]);
$selected = $this->capitalize_first_letter($selected);
$replacement = ' ' . esc_html($selected) . ' ';
$result .= $replacement;
$char_count = 0;
}
}
}
return $result;
}
// Viết hoa chữ cái đầu tiên của chuỗi
private function capitalize_first_letter($string) {
return mb_strtoupper(mb_substr($string, 0, 1)) . mb_substr($string, 1);
}
// Xử lý spin cho các bộ lọc khác (tiêu đề, meta, v.v.)
public function spin_text_general($text) {
if (is_admin()) {
return $text;
}
// Lấy dữ liệu spin global (category_id = 0)
$spin_data = $this->get_spin_data(0);
if (!$spin_data) {
return $text;
}
// Xử lý spin có sẵn trước
$text = $this->process_existing_spins($text);
// Áp dụng spin level 1
$spin_level1 = $spin_data['spin_level1'];
if (!empty($spin_level1)) {
$spin_options = explode('|', $this->process_existing_spins($spin_level1));
if (!empty($spin_options)) {
$selected = trim($spin_options[array_rand($spin_options)]);
$selected = $this->capitalize_first_letter($selected);
$text = preg_replace('/(\s|^)([^\s<]+)(\s|$)/', '$1' . $selected . '$3', $text);
}
}
return $text;
}
}
// Khởi chạy plugin
DataSpinPlugin::init();