Elementor 使用数据上报 Schema 全解析:usage.json 结构与 usage 追踪实现
【免费下载链接】elementorThe most advanced frontend drag & drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.项目地址: https://gitcode.com/GitHub_Trending/el/elementor
本篇指南以 Elementor 开源仓库中的 usage schema 演进记录 与 usage.json JSON Schema 定义 为核心,系统讲解 Elementor 匿名使用数据(Usage Tracking)的上报数据模型:从顶层字段、system环境信息、usages统计维度,到posts、library、elements、settings等各数据块的字段含义与枚举约束,并结合 includes/tracker.php 与 modules/usage/module.php 的源码实现与测试用例,帮助读者完整掌握这份 Schema 的数据结构、演进历史与底层统计逻辑,具备直接阅读、校验甚至扩展 Elementor 使用数据格式的能力。
一、先认识关联文档:一份记录 Schema 演进的 Changelog
仓库中 tests/phpunit/schemas/readme.md 全篇是一份精简的 Changelog,记录了usage.json这个使用数据 Schema 在两次版本迭代中的结构变化:
| Schema 版本 | 变更内容 | 对应数据块 |
|---|---|---|
3.3.0 | 新增usage/non-elementor-posts,用于统计未使用 Elementor 构建的文章数量 | usages.non-elementor-posts |
3.5.0 | 新增usage/library-details,为每种 post-type 补充 library 模板的详细数量 | usages.library-details |
这两次演进揭示了一个重要设计思路:Elementor 的使用数据上报(Usage Tracking)不仅要统计"用了 Elementor 的内容",还要统计"没用的内容"作为对照(non-elementor-posts),同时把模板库的统计从"按模板类型汇总"(library)细化到"按模板类型 + 文章状态"(library-details)。后文将结合源码逐一还原这两条记录的实现。
而 Changelog 所描述的承载对象,就是同一目录下的核心文件 usage.json(JSON Schema draft-07 格式,共 1387 行),它是本文的主体。
二、usage.json 顶层结构:一次上报请求包含什么
usage.json声明了上报数据的根节点类型为object,并设置了 4 个顶层必填字段:
"required": [ "system", "site_lang", "email", "usages" ]同时,根节点还允许出现以下可选字段(均通过additionalProperties: false严格约束,任何未声明字段都会被 Schema 校验器拒绝):
| 顶层字段 | 类型 | 含义 |
|---|---|---|
system | object(必填) | 站点运行环境:服务器、WordPress、主题、插件等 |
site_lang | string(必填) | 站点语言,LCID 格式,如en-US |
email | string(必填) | 管理员邮箱,受^\S+@\S+$正则约束 |
usages | object(必填) | Elementor 各组件使用情况统计 |
is_first_time | boolean | 是否为首次上报使用数据 |
install_time | number | 安装时间戳 |
allowed_usage_time | number | 允许统计的起始时间点 |
site_key | string | 站点唯一标识 |
analytics_events | array | 同意共享使用数据的用户的行为事件数组 |
这一结构与 includes/tracker.php 中Tracker::get_tracking_data()的构造逻辑完全对应:该方法先组装system、site_lang、email、usages四个必填块,再按条件附加is_first_time、install_time、site_key、allowed_usage_time,最后通过elementor/tracker/send_tracking_data_params过滤器允许其他模块(如 modules/usage/module.php 中的add_tracking_data)继续追加数据。值得注意的是,email字段在 Schema 中带有一条注释TODO: Remove duplicated data,说明它同时在system.wordpress.admin_email与顶层各出现一次,属于已知的冗余设计。
2.1 全局复用的枚举定义
Schema 的definitions.global定义了 4 组被多处$ref引用的字符串枚举,理解它们有助于读懂后续所有字段:
| 枚举名 | 取值 | 典型用途 |
|---|---|---|
yes_no | "Yes"/"No" | 布尔式状态,如system.server.gd_installed |
yes_no_lowercase | "yes"/"no" | 小写布尔式状态,如usages.settings.general.allow_tracking |
active_inactive | "Active"/"Inactive" | 启停状态,如system.wordpress.debug_mode |
active_inactive_lowercase | "active"/"inactive" | 实验功能状态,如usages.settings.experiments.*.default |
三、system 数据块:服务器、WordPress、主题与插件环境
system是描述站点运行环境的核心对象,必填字段为server、wordpress、theme、plugins,可选字段包括user、network_plugins、mu_plugins、elementor_compatibility。
3.1 server:Web 服务器环境
必填字段共 11 个,覆盖了排查环境问题时最关心的信息:
| 字段 | 类型/枚举 | 说明与示例 |
|---|---|---|
os | string | 服务器操作系统,如Darwin |
software | string | HTTP 服务器类型与版本,如Apache/2.4.46 (Unix) PHP/7.2.34 |
mysql_version | string | MySQL 版本,如Homebrew v10.5.8 |
php_version | string | PHP 版本,如7.2.34 |
php_memory_limit | string | PHP 内存上限,如128M |
php_max_input_vars | string | PHP 允许的最大输入变量数,如1000 |
php_max_post_size | string | PHP 允许的最大 POST 体积,如8M |
gd_installed | yes_no | 是否安装 GD 图像处理扩展 |
zip_installed | yes_no | 是否安装 zip 扩展 |
write_permissions | string | 目录写权限检查结果,正常为All right,异常时为问题文件列表 |
elementor_library | string | Elementor 库连接状态,格式为Connected或Not connected (错误信息) |
3.2 wordpress:WordPress 环境
12 个必填字段中值得注意的有:
is_multisite:是否多站点,默认No,复用yes_no枚举;max_upload_size:最大上传大小,示例2 MB;memory_limit与max_memory_limit:分别描述普通请求与后台管理请求的内存上限(示例40M/256M);permalink_structure:固定链接结构,如/blog/%year%/%monthnum%/%day%/%postname%/;language:WordPress 语言(LCID 格式,如en-US);timezone:GMT 偏移量,可为负;admin_email:引用全局email定义;debug_mode:调试模式是否开启,复用active_inactive,默认Inactive。
3.3 theme 与 user
theme记录当前主题的name、version、author与is_child_theme(是否子主题,yes_no枚举)。其中version与author的类型均为["string", "boolean"]联合类型,默认值false,用于兼容主题头部信息缺失的情况。
user为可选块(注释标记Optional),描述当前登录用户:role(可为null或字符串,如administrator)、locale(如en_US)、agent(浏览器 User-Agent 字符串)。
3.4 plugins 体系:active / network / must-use 三层插件
definitions.plugins是插件对象的通用定义:键名通过patternProperties匹配.*\.php$(插件主文件路径,如elementor/elementor.php),每个插件对象必填 14 个字段:Elementor tested up to、Name、PluginURI、Version、Description、Author、AuthorURI、TextDomain、DomainPath、Network、RequiresWP、RequiresPHP、Title、AuthorName。
其中Elementor tested up to表示该插件兼容测试到的 Elementor 最高版本;Network为布尔值,标识是否为 WordPress 多站点网络级插件。system.plugins.active_plugins引用该定义,并额外要求必须包含elementor/elementor.php(即 Elementor 自身必须是已激活插件,这是 Schema 的硬性约束);network_plugins.network_active_plugins与mu_plugins.must_use_plugins同样引用该定义,分别覆盖网络激活插件与必须使用(must-use)插件。elementor_compatibility为可选对象,记录各插件与 Elementor 的兼容状态。
四、usages 数据块:从文章、模板到控件级使用统计
usages是整份 Schema 中信息量最大的部分,必填字段为posts、non-elementor-posts、library、library-details、elements,另有favorites、settings、tools、connect、kit、onboarding_features、global_classes等可选块。
4.1 posts 与 non-elementor-posts:Elementor 覆盖率的正反两面
两者共用同一个定义posts_per_type_per_post_status,其结构为"文章类型 → 文章状态 → 数量"的二级嵌套:
{ "type": ["object", "array"], "patternProperties": { "([^\\s]+)": { "patternProperties": { "(draft|pending|private|publish|inherit|trash)$": { "type": "integer", "title": "Count of post(s) per post-type" } }, "additionalProperties": false } }, "additionalProperties": false }内层键被正则严格限定为六种文章状态之一:draft(草稿)、pending(待审)、private(私密)、publish(已发布)、inherit(继承,如附件)、trash(回收站)。non-elementor-posts在 Schema 中给出了一组真实示例:
{ "attachment": { "inherit": 15 }, "elementor_snippet": { "auto-draft": 1, "publish": 1 }, "page": { "draft": 1, "publish": 1 }, "post": { "auto-draft": 2 } }对应的底层实现分别位于 includes/tracker.php 的get_posts_usage()与 includes/tracker.php 的get_non_elementor_posts_usage(),两条 SQL 的区别在于 JOIN 条件:
- 统计 Elementor 文章时,筛选
meta_key = '_elementor_edit_mode' AND meta_value = 'builder'的文章并按post_type、post_status分组计数,且排除elementor_library类型; - 统计非 Elementor 文章时(3.3.0 新增),通过
LEFT JOIN后取meta_value IS NULL的行,即没有_elementor_edit_mode元数据的文章,从而得到"站点中未用 Elementor 构建的内容"数量,两个数据块配合即可计算 Elementor 在站点中的覆盖率。
4.2 library 与 library-details:模板库的两代统计口径
usages.library:键为模板类型(patternProperties匹配[^\s]+,如section、page、widget、kit),值为该类型的模板总数(type: string,Schema 注释标明TODO: Should be number,即历史遗留的类型不严谨之处)。usages.library-details(3.5.0 新增):键为模板类型,值为count_per_post_status定义——按文章状态细分的数量对象,状态键同样受(draft|pending|private|publish|inherit|trash)$正则约束。Schema 示例:
{ "kit": { "publish": 1 }, "page": { "draft": 3 }, "section": { "draft": 1, "publish": 1 }, "widget": { "draft": 1, "publish": 1, "trash": 2 } }实现上,includes/tracker.php 的get_library_usage()只按_elementor_template_type分组计数;而 includes/tracker.php 的get_library_usage_extend()在GROUP BY中额外加入了post_status,从而产出按"模板类型 + 状态"细分的library-details。两代口径并存,正是 Changelog 中 3.5.0 变更的代码落点。
4.3 elements:控件级使用统计(最深的数据维度)
usages.elements是 Schema 中层级最深的数据块,采用"文档类型 → 元素类型 → 元素统计 → 控件统计"的四级结构:
{ "type": ["object", "boolean"], "description": "Usage of controls per document-type.", "patternProperties": { "([^\\s]+)": { "patternProperties": { "([^\\s]+)": { "required": ["count", "controls"], "properties": { "count": { "type": "number" }, "control_percent": { "type": "number" }, "controls": { "patternProperties": { "(content|style|advanced|layout|general)$": { ... } } } } } } } } }每个元素对象必填count(元素在文档类型中的使用次数)与controls,可选control_percent(被修改控件占该元素全部控件的百分比)。controls的键被正则限定为五个标签页:content、style、advanced、layout、general,每个标签页下再按"分区(section)→ 控件名 → 使用次数"层层嵌套。
general标签页有特殊子结构:__dynamic__(动态标签)下包含一个count字段,用于统计使用动态标签(Dynamic Tags)的次数。这一点在测试用例 tests/phpunit/elementor/schemas/test-usage.php 中得到验证:断言$usage['elements']['wp-post']['heading']['controls']['general']中必须包含__dynamic__键。
该结构的实际生成逻辑在 modules/usage/module.php 的get_elements_usage()中:通过Plugin::$instance->db->iterate_data()遍历文档的_elementor_data,区分widgetType(控件)与elType(元素)后,交由"使用计算器"处理。计算器体系由 contracts/element-usage-calculator.php 定义的Element_Usage_Calculator接口(can_calculate/calculate)与 element-usage-calculator-registry.php 注册表组成:Atomic Widgets 模块激活时优先使用Atomic_Element_Usage_Calculator,否则回退到 calculators/legacy-element-usage-calculator.php 的Legacy_Element_Usage_Calculator。
以 Legacy 计算器为例,其calculate()会累加元素计数,并遍历元素 settings 中与默认值不同的控件(add_controls内if ( $value !== $control_config['default'] )判定),按tab、section、control三级键递增计数,同时计算control_percent = 变更控件数 / (控件总数 / 100)后四舍五入。动态标签则通过add_general_controls()归入general标签页的__dynamic__分组。
4.4 settings 与 tools:非默认配置上报
usages.settings按general、advanced、performance、experiments四个子块组织,仅上报非默认值的配置(这从实现端 modules/usage/module.php 的get_settings_usage()可以看出:跳过隐藏字段、跳过默认值)。Schema 为每个字段给出了完整枚举与默认值,例如:
general:cpt_support(支持的 post-type 数组)、disable_color_schemes(""/"yes")、disable_typography_schemes(""/"yes")、allow_tracking(yes_no_lowercase,默认yes);advanced:editor_break_lines(""/"1",默认1)、unfiltered_files_upload、google_font("1"/"0",默认1)、font_display(auto/block/swap/fallback/optional,默认auto)、load_fa4_shim(默认yes)、meta_generator_tag;performance:css_print_method(internal/external,默认internal)、optimized_image_loading、optimized_gutenberg_loading、lazy_load_background_images;experiments:每个实验对象包含default(active/inactive)、state(active/inactive/default三者 oneOf)、tags(type+label对象数组)。
usages.tools类似地分为general(safe_mode为""/global、enable_inspector为""/enable)、version(beta是否参与 Beta 测试,默认no)、maintenance(maintenance_mode_mode为""/coming_soon/maintenance,maintenance_mode_exclude_mode为logged_in/custom,另有maintenance_mode_exclude_roles角色数组与maintenance_mode_template_id模板 ID)。
4.5 其余可选数据块
favorites:按收藏类型(favorite-type)列出被收藏的元素 ID 字符串数组;connect:Elementor Connect 授权信息,含site_key(string/boolean)、count(用户数)、users数组(每项含id、email、roles,注释提醒 id 仅在单个 WP 站点内唯一);kit:Elementor Kit 使用情况,defaults内含count(整数)与elements(字符串数组);onboarding_features:引导流程(Onboarding)启用的功能名称字符串数组;global_classes:全局类(Global Classes)统计,total_count为总数,applied_classes_per_element_type按元素类型记录应用次数。
五、Schema 的实战用法:校验、报告与重新计算
5.1 用 PHPUnit 校验真实上报数据
仓库将 Schema 直接用于测试,tests/phpunit/elementor/schemas/test-usage.php 通过JsonSchema\Exception\ValidationException与ElementorEditorTesting\Base_Schema基类做了四类验证:
test__ensure_clean_is_valid:在插件 mock 数据下,用Tracker::get_tracking_data()生成的完整数据必须通过 Schema 校验;test__ensure_invalid_exception:空数组[]必须触发ValidationException(因为缺少必填字段);test__ensure_all_objects_have_no_additional_properties:断言 Schema 中所有对象都设置了additionalProperties: false,保证数据格式的封闭性;test__ensure_tracking_data_with_usage_full_mock:构造尽可能完整的"全量 mock"——创建普通文章、创建not-supported模板、发布含动态标签(Dynamic Tags)的文档、注册Title/Link两个测试动态标签、写入 Connect 假数据等,再断言posts、library、elements(含wp-post文档类型下的 4 个元素与__dynamic__控件)均存在,最后整体通过 Schema 校验。
运行方式为仓库标准的 PHPUnit 测试流程(参见 docs/devlopment/phpunit.md),Schema 本身则通过其$schema声明(http://json-schema.org/draft-07/schema)可被任何 JSON Schema 校验器(如 ajv、json-schema-validator)离线复用。
5.2 在系统信息面板查看与重算
usages模块在 modules/usage/module.php 的add_system_info_report()中注册了两个系统信息(System Info)报告器:
- usage-reporter.php:
Elements Usage报告,遍历elementor_controls_usage选项,按文档类型列出各元素的计数;页面中带有一个Recalculate链接,通过elementor_usage_recalc查询参数触发Module::recalc_usage()全量重算; - settings-reporter.php:
Settings报告,输出Module::get_settings_usage()收集的非默认设置项。
重算逻辑 recalc_usage() 支持分页参数$limit/$offset(偏移为 0 时先清空旧选项),通过WP_Query查询所有带_elementor_data元数据的publish/private文章,逐一执行after_document_save()重新累计,适合站点数据迁移或数据损坏后的重建场景。
5.3 数据生命周期:何时写入、何时扣除
从 modules/usage/module.php 的构造器可以看出模块只在用户允许追踪(Tracker::is_allow_track())时启用,并挂载了四个生命周期钩子:
transition_post_status:文章状态迁移时,若从publish/private移出则remove_from_global()扣除旧统计,迁入则save_document_usage()累加;before_delete_post:删除文章前扣除其用量;elementor/document/before_save与elementor/document/after_save:编辑器内保存文档时,先移除旧统计再写入新统计;elementor/tracker/send_tracking_data_params:把elementor_controls_usage选项(即usages.elements数据)注入上报参数。
单篇文档的用量存于文章 meta_elementor_controls_usage,全站聚合存于选项elementor_controls_usage,Schema 中usages.elements的结构与后者完全一致。这种"逐文档记账 + 全局聚合"的设计,使得 Schema 校验通过的数据可以直接用于站点健康度分析、插件兼容性排查等功能。
六、小结
以 readme.md 这份两行的 Changelog 为索引,可以完整还原 Elementor 使用数据 Schema 的演进脉络:3.3.0 引入的non-elementor-posts让统计数据具备了"未使用 Elementor 内容"的对照维度,3.5.0 引入的library-details将模板库统计细化到状态粒度。而 usage.json 本身则通过严格的 JSON Schema(必填约束、正则枚举、additionalProperties: false)约束着从system环境信息到usages.elements控件级计数的全部上报字段,其背后是 includes/tracker.php 的 SQL 聚合、modules/usage/module.php 的逐文档记账,以及 tests/phpunit/elementor/schemas/test-usage.php 的持续校验。对开发者而言,这份 Schema 既是理解 Elementor 数据上报的"契约文档",也是可复用的数据格式参考——它完整定义了一款 WordPress 页面构建器产品在做匿名使用统计时,会关注哪些环境指标与使用行为维度。
【免费下载链接】elementorThe most advanced frontend drag & drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.项目地址: https://gitcode.com/GitHub_Trending/el/elementor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考