WPSlug 与 All-in-One WP Migration 等插件的 CSS 冲突修复

·0 次浏览
  • 作者
    帖子
  • wenpai@wenpai
    楼主

    问题

    WPSlug(文派素格) 的 sanitize_title 过滤器 (priority 9) 会拦截 WordPress 核心 add_menu_page() 内部的 sanitize_title() 调用。 WordPress 用该调用生成 admin page hook suffix($admin_page_hooks[$menu_slug]) 。

    当 All-in-One WP Migration(AIOWPM) 注册菜单 add_menu_page('All-in-One WP Migration', ...) 时:

    • 无 WPSlug: hook suffix = all-in-one-wp-migration(正确)
    • 有 WPSlug: 优化器 stop word 移除把 「in」 删掉 → hook suffix = all-one-wp-migration(错误)

    AIOWPM 的 enqueue_import_scripts_and_styles($hook) 用 stripos 硬匹配 all-in-one-wp-migration_page_ai1wm_import,被篡改的 hook 不匹配 → CSS/JS 不加载 → 导入页样式全部丢失。

    影响范围:不仅 AIOWPM,任何菜单标题含 stop word(in/on/at/to/for/of/with/by/a/an/the) 的插件都受影响。

    根因分析

    sanitize_title() 在 WordPress 中有两种用途:

    1. 内容 slug 生成:post/term/media 保存时,需要拼音转换和 stop word 优化
    2. 内部标识符生成:add_menu_page() 在 admin_menu action 期间调用,生成 hook suffix 用于页面识别

    WPSlug 没有区分这两种场景,导致内部标识符也被优化。

    修复方案

    在 processSanitizeTitle() 守卫条件中增加 doing_action() 检测,跳过 admin 菜单注册期间的调用:

    // Skip during admin menu registration — sanitize_title() is used to
    // generate hook suffixes, not content slugs.
    if (doing_action('admin_menu') || doing_action('network_admin_menu') || doing_action('user_admin_menu')) {
        return $title;
    }
    

    为什么安全

    • add_menu_page() 在 admin_menu action 期间调用 sanitize_title() 生成 hook suffix,这不是内容 slug,不应被转换
    • 真正的 post/term slug 保存不在 admin_menu action 期间执行,零误伤
    • 同时覆盖了 network_admin_menu 和 user_admin_menu,Multisite 场景也安全

    验证结果

    在 wapuu.com 测试站上同时启用 WPSlug + AIOWPM:

    • admin_menu 期间 sanitize_title("All-in-One WP Migration") → all-in-one-wp-migration ✓(「in」 保留)
    • hook 完整匹配 all-in-one-wp-migration_page_ai1wm_import ✓
    • 回归测试:中文 slug 转换不受影响 ✓

Cyberforums · 原文 · Markdown

想回复或继续讨论?请到 Cyberforums 赛博论坛参与。

参与讨论 / 回复