Plugin Directory

Changeset 3398580


Ignore:
Timestamp:
11/19/2025 07:26:22 AM (4 months ago)
Author:
infility
Message:

v2.14.31 (20251119) Ben: 新增导入term的seo标题和描述

Location:
infility-global/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • infility-global/trunk/infility_global.php

    r3397907 r3398580  
    44Plugin URI: https://www.infility.cn/
    55Description: Infility公共插件
    6 Version: 2.14.30
     6Version: 2.14.31
    77Author: Infility
    88Author URI: https://www.infility.cn/
     
    132132V2.14.27 (20251113) Ben: 新增古腾堡特殊处理工具
    133133V2.14.28 (20251114) Ben: 新增导入seo标题和描述
     134v2.14.31 (20251119) Ben: 新增导入term的seo标题和描述
    134135*/
    135136
     
    137138    function __construct()
    138139    {
    139         define( 'INFILITY_GLOBAL_VERSION', '2.14.30' );
     140        define( 'INFILITY_GLOBAL_VERSION', '2.14.31' );
    140141        define( 'INFILITY_GLOBAL_PATH', plugin_dir_path( __FILE__ ) ); // fullpath/wp-content/plugins/infility-global/ // 有斜杠
    141142        define( 'INFILITY_GLOBAL_URL', plugins_url( '/', __FILE__ ) ); // https://the_domain/wp-content/plugins/infility-global/ // 斜杠是自己加的
  • infility-global/trunk/readme.txt

    r3395561 r3398580  
    361361= 2.14.28 =
    362362新增导入seo标题和描述
     363
     364= 2.14.31 =
     365新增导入term的seo标题和描述
  • infility-global/trunk/widgets/infility-import-data/include/infility-import-seo.php

    r3395561 r3398580  
    249249        }
    250250
     251        /**
     252         * 根据链接查找 taxonomy term(返回 [term_id, taxonomy] 或 [0, ''])
     253         */
     254        public static function get_term_by_url($url) {
     255            $url = trim((string)$url);
     256            if ($url === '') { return [0, '']; }
     257
     258            $taxonomies = get_taxonomies(['public' => true]);
     259
     260            // 查询参数匹配:?taxonomy=product_cat&term=slug、?product_cat=slug、?cat=ID
     261            $query_str = parse_url($url, PHP_URL_QUERY);
     262            if (is_string($query_str) && $query_str !== '') {
     263                parse_str($query_str, $qs);
     264
     265                if (!empty($qs['cat']) && is_numeric($qs['cat'])) {
     266                    $term = get_term((int)$qs['cat'], 'category');
     267                    if ($term && !is_wp_error($term)) { return [$term->term_id, 'category']; }
     268                }
     269
     270                if (!empty($qs['taxonomy']) && !empty($qs['term'])) {
     271                    $tax = sanitize_key($qs['taxonomy']);
     272                    $slug = sanitize_title(urldecode($qs['term']));
     273                    $term = get_term_by('slug', $slug, $tax);
     274                    if ($term && !is_wp_error($term)) { return [$term->term_id, $tax]; }
     275                }
     276
     277                foreach ($taxonomies as $tax) {
     278                    if (!empty($qs[$tax])) {
     279                        $val = $qs[$tax];
     280                        if (is_numeric($val)) {
     281                            $term = get_term((int)$val, $tax);
     282                            if ($term && !is_wp_error($term)) { return [$term->term_id, $tax]; }
     283                        } else {
     284                            $slug = sanitize_title(urldecode($val));
     285                            $term = get_term_by('slug', $slug, $tax);
     286                            if ($term && !is_wp_error($term)) { return [$term->term_id, $tax]; }
     287                        }
     288                    }
     289                }
     290            }
     291
     292            // 路径匹配:根据 taxonomy 的 rewrite slug,如 /product-category/<slug>
     293            $path = parse_url($url, PHP_URL_PATH);
     294            if (is_string($path)) {
     295                $path = trim($path, "/\\");
     296                $segments = array_values(array_filter(explode('/', $path), 'strlen'));
     297                if (!empty($segments)) {
     298                    foreach ($taxonomies as $tax) {
     299                        $tax_obj = get_taxonomy($tax);
     300                        if (!$tax_obj || empty($tax_obj->rewrite) || empty($tax_obj->rewrite['slug'])) { continue; }
     301                        $base = trim($tax_obj->rewrite['slug'], "/\\");
     302                        $index = array_search($base, $segments, true);
     303                        if ($index !== false) {
     304                            $sub = array_slice($segments, $index + 1);
     305                            if (!empty($sub)) {
     306                                $slug = sanitize_title(urldecode(end($sub)));
     307                                if ($slug !== '') {
     308                                    $term = get_term_by('slug', $slug, $tax);
     309                                    if ($term && !is_wp_error($term)) { return [$term->term_id, $tax]; }
     310                                }
     311                            }
     312                        }
     313                    }
     314
     315                    // 回退:最后一段作为 slug,尝试所有 taxonomy
     316                    $slug = sanitize_title(urldecode(end($segments)));
     317                    if ($slug !== '') {
     318                        foreach ($taxonomies as $tax) {
     319                            $term = get_term_by('slug', $slug, $tax);
     320                            if ($term && !is_wp_error($term)) { return [$term->term_id, $tax]; }
     321                        }
     322                    }
     323                }
     324            }
     325
     326            return [0, ''];
     327        }
     328
     329        /** 更新 taxonomy 的 SEO 标题与描述(跳过空白) */
     330        public static function update_term_seo_meta($term_id, $taxonomy, $title, $description) {
     331            $updated_keys = [];
     332            $title = is_string($title) ? trim($title) : '';
     333            $description = is_string($description) ? trim($description) : '';
     334            if ($title === '' && $description === '') { return $updated_keys; }
     335
     336            // Yoast:优先通过 WPSEO_Taxonomy_Meta 写入 wp_options: wpseo_taxonomy_meta
     337            if (function_exists('YoastSEO') && class_exists('WPSEO_Taxonomy_Meta')) {
     338                $yoast_meta = [];
     339                if ($title !== '') { $yoast_meta['wpseo_title'] = $title; }
     340                if ($description !== '') { $yoast_meta['wpseo_desc'] = $description; }
     341                if (!empty($yoast_meta)) {
     342                    \WPSEO_Taxonomy_Meta::set_values((int)$term_id, (string)$taxonomy, $yoast_meta);
     343                    $updated_keys = array_merge($updated_keys, array_keys($yoast_meta));
     344                }
     345            } else {
     346                // 兼容旧逻辑(极少数场景):写入 termmeta
     347                if ($title !== '') { update_term_meta($term_id, 'wpseo_title', $title); $updated_keys[] = 'wpseo_title'; }
     348                if ($description !== '') { update_term_meta($term_id, 'wpseo_desc', $description); $updated_keys[] = 'wpseo_desc'; }
     349            }
     350
     351            // Rank Math
     352            if ($title !== '') { update_term_meta($term_id, 'rank_math_title', $title); $updated_keys[] = 'rank_math_title'; }
     353            if ($description !== '') { update_term_meta($term_id, 'rank_math_description', $description); $updated_keys[] = 'rank_math_description'; }
     354
     355            // All in One SEO(兼容新版/旧版常见键名)
     356            if ($title !== '') {
     357                update_term_meta($term_id, 'aioseo_title', $title);
     358                update_term_meta($term_id, '_aioseop_title', $title);
     359                $updated_keys[] = 'aioseo_title';
     360                $updated_keys[] = '_aioseop_title';
     361            }
     362            if ($description !== '') {
     363                update_term_meta($term_id, 'aioseo_description', $description);
     364                update_term_meta($term_id, '_aioseop_description', $description);
     365                $updated_keys[] = 'aioseo_description';
     366                $updated_keys[] = '_aioseop_description';
     367            }
     368
     369            return $updated_keys;
     370        }
     371
    251372        /** 主执行:读取XLSX并导入SEO元数据 */
    252373        public static function run($filePath) {
     
    296417                }
    297418
     419                $updated_terms = 0;
     420                $updated_posts = 0;
    298421                for ($r = 1; $r < count($rows); $r++) {
    299422                    $row = $rows[$r];
     
    312435
    313436                    $post_id = self::get_post_id_by_url($address);
    314                     if (!$post_id) {
    315                         $summary['not_found']++;
     437                    if ($post_id) {
     438                        $updated_keys = self::update_seo_meta($post_id, $title, $desc);
     439                        if (!empty($updated_keys)) {
     440                            $summary['updated']++;
     441                            $updated_posts++;
     442                            if (count($summary['samples']) < 10) {
     443                                $summary['samples'][] = [
     444                                    'type' => 'post',
     445                                    'post_id' => $post_id,
     446                                    'address' => $address,
     447                                    'title' => $title,
     448                                    'description' => $desc,
     449                                    'keys' => $updated_keys,
     450                                ];
     451                            }
     452                        } else {
     453                            $summary['skipped_blank']++;
     454                        }
    316455                        continue;
    317456                    }
    318457
    319                     $updated_keys = self::update_seo_meta($post_id, $title, $desc);
    320                     if (!empty($updated_keys)) {
    321                         $summary['updated']++;
    322                         if (count($summary['samples']) < 10) {
    323                             $summary['samples'][] = [
    324                                 'post_id' => $post_id,
    325                                 'address' => $address,
    326                                 'title' => $title,
    327                                 'description' => $desc,
    328                                 'keys' => $updated_keys,
    329                             ];
    330                         }
    331                     } else {
    332                         $summary['skipped_blank']++;
    333                     }
     458                    list($term_id, $taxonomy) = self::get_term_by_url($address);
     459                    if ($term_id) {
     460                        $updated_keys = self::update_term_seo_meta($term_id, $taxonomy, $title, $desc);
     461                        if (!empty($updated_keys)) {
     462                            $summary['updated']++;
     463                            $updated_terms++;
     464                            if (count($summary['samples']) < 10) {
     465                                $summary['samples'][] = [
     466                                    'type' => 'term',
     467                                    'term_id' => $term_id,
     468                                    'taxonomy' => $taxonomy,
     469                                    'address' => $address,
     470                                    'title' => $title,
     471                                    'description' => $desc,
     472                                    'keys' => $updated_keys,
     473                                ];
     474                            }
     475                        } else {
     476                            $summary['skipped_blank']++;
     477                        }
     478                        continue;
     479                    }
     480
     481                    $summary['not_found']++;
    334482                }
    335483            } catch (Throwable $e) {
     
    340488            $message[] = '<p>SEO导入完成</p>';
    341489            $message[] = '<p>总数据行: ' . $summary['total_rows'] . '</p>';
    342             $message[] = '<p>成功更新: ' . $summary['updated'] . '</p>';
     490            $message[] = '<p>成功更新: ' . $summary['updated'] . '(文章/页面:' . $updated_posts . ',分类/标签等:' . $updated_terms . ')</p>';
    343491            $message[] = '<p>空白跳过: ' . $summary['skipped_blank'] . '</p>';
    344492            $message[] = '<p>未匹配到: ' . $summary['not_found'] . '</p>';
     
    349497                $message[] = '<p>示例(最多10条):</p>';
    350498                foreach ($summary['samples'] as $s) {
    351                     $message[] = sprintf('<p>- ID %d | %s | %s | %s</p>', $s['post_id'], $s['address'], $s['title'], $s['description']);
     499                    if (!empty($s['type']) && $s['type'] === 'term') {
     500                        $message[] = sprintf('<p>- Term #%d [%s] | %s | %s | %s</p>', $s['term_id'], esc_html($s['taxonomy']), esc_html($s['address']), esc_html($s['title']), esc_html($s['description']));
     501                    } else {
     502                        $message[] = sprintf('<p>- Post #%d | %s | %s | %s</p>', $s['post_id'], esc_html($s['address']), esc_html($s['title']), esc_html($s['description']));
     503                    }
    352504                }
    353505            }
Note: See TracChangeset for help on using the changeset viewer.