feat(widgets): complete phase 3 atomic integration
This commit is contained in:
@@ -12,6 +12,11 @@ if (!function_exists('sanitize_text_field')) {
|
||||
return trim(preg_replace('/[\r\n\t]+/', ' ', strip_tags((string) $value)) ?? '');
|
||||
}
|
||||
}
|
||||
if (!function_exists('__')) {
|
||||
function __($text): string {
|
||||
return (string) $text;
|
||||
}
|
||||
}
|
||||
if (!function_exists('sanitize_textarea_field')) {
|
||||
function sanitize_textarea_field($value): string {
|
||||
return trim(strip_tags((string) $value));
|
||||
@@ -45,7 +50,9 @@ require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
use AKSRT\WidgetSystem\FieldSchema;
|
||||
use AKSRT\WidgetSystem\PostQuery;
|
||||
use AKSRT\WidgetSystem\RendererRegistry;
|
||||
use AKSRT\WidgetSystem\WidgetAreas;
|
||||
use AKSRT\WidgetSystem\WidgetRegistry;
|
||||
use AKSRT\WidgetSystem\WidgetTransfer;
|
||||
|
||||
$errors = [];
|
||||
$expected = [
|
||||
@@ -65,6 +72,36 @@ if (array_keys($registry) !== $expected) {
|
||||
$errors[] = 'Registry slugs or ordering differ from the frozen contract.';
|
||||
}
|
||||
|
||||
$expected_areas = [
|
||||
'all_top_fluid', 'all_bottom_fluid', 'all_sidebar_top', 'all_sidebar_bottom',
|
||||
'home_top_fluid', 'home_top_content', 'home_bottom_content', 'home_bottom_fluid', 'home_sidebar',
|
||||
'single_top_fluid', 'single_top_content', 'single_bottom_content', 'single_bottom_fluid', 'single_sidebar',
|
||||
'cat_top_fluid', 'cat_top_content', 'cat_bottom_content', 'cat_bottom_fluid', 'cat_sidebar',
|
||||
'tag_top_fluid', 'tag_top_content', 'tag_bottom_content', 'tag_bottom_fluid', 'tag_sidebar',
|
||||
'search_top_fluid', 'search_top_content', 'search_bottom_content', 'search_bottom_fluid', 'search_sidebar',
|
||||
'author_top_fluid', 'author_bottom_fluid', 'msg_top_fluid', 'msg_bottom_fluid',
|
||||
'user_top_fluid', 'user_top_content', 'user_bottom_fluid',
|
||||
'newposts_sidebar_top', 'newposts_sidebar_bottom', 'all_footer', 'mobile_nav_fluid',
|
||||
];
|
||||
if (WidgetAreas::static_ids() !== $expected_areas || count(WidgetAreas::static_ids()) !== 40) {
|
||||
$errors[] = 'Widget area registry must contain the exact 40 static areas.';
|
||||
}
|
||||
|
||||
$templates = WidgetTransfer::templates();
|
||||
$expected_templates = ['article_home', 'article_list', 'links_navigation', 'article_sidebar', 'knowledge_landing'];
|
||||
if (array_keys($templates) !== $expected_templates || count($templates) !== 5) {
|
||||
$errors[] = 'Import/export must expose the exact five built-in templates.';
|
||||
}
|
||||
foreach ($templates as $template => $contract) {
|
||||
foreach ((array) ($contract['sidebars'] ?? []) as $items) {
|
||||
foreach ((array) $items as $item) {
|
||||
if (!isset($registry[(string) ($item['widget'] ?? '')])) {
|
||||
$errors[] = $template . ': template contains an unknown widget.';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$supported = FieldSchema::supported_types();
|
||||
$walk = static function (array $fields, string $owner) use (&$walk, &$errors, $supported): void {
|
||||
$ids = [];
|
||||
@@ -173,6 +210,62 @@ foreach ($frontend_files as $frontend_file) {
|
||||
}
|
||||
}
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
$legacy_paths = [
|
||||
'/src/Core/WidgetAjax.php',
|
||||
'/src/Core/SetupPart1.php',
|
||||
'/src/Widgets',
|
||||
'/inc/modules/widgets-register.php',
|
||||
'/inc/modules/widget-common.php',
|
||||
'/inc/modules/widget-areas.php',
|
||||
'/assets/css/frontend/widgets.css',
|
||||
'/assets/css/frontend/widgets',
|
||||
'/assets/css/frontend/widget-batch5.css',
|
||||
'/assets/js/widget-set.js',
|
||||
];
|
||||
foreach ($legacy_paths as $legacy_path) {
|
||||
if (file_exists($root . $legacy_path)) {
|
||||
$errors[] = 'Legacy widget runtime remains: ' . $legacy_path;
|
||||
}
|
||||
}
|
||||
|
||||
$runtime_source = (string) file_get_contents($root . '/src/WidgetSystem/Runtime.php');
|
||||
foreach (['WidgetAreas::class', 'WidgetRegistry::all()', 'register_widget(new SchemaWidget', 'unregister_core_widgets'] as $contract) {
|
||||
if (!str_contains($runtime_source, $contract)) {
|
||||
$errors[] = 'Widget runtime missing contract: ' . $contract;
|
||||
}
|
||||
}
|
||||
$asset_source = (string) file_get_contents($root . '/src/WidgetSystem/AssetManager.php');
|
||||
if (str_contains($asset_source, 'cdn.jsdelivr.net')) {
|
||||
$errors[] = 'Widget assets must not use CDN dependencies.';
|
||||
}
|
||||
$admin_import_sources = (string) file_get_contents($root . '/src/Admin/ImportExportController.php')
|
||||
. (string) file_get_contents($root . '/src/Admin/ImportExportControllerPart1.php');
|
||||
foreach (['/widgets/export', '/widgets/import', '/widgets/templates', 'aksrt_widget_templates'] as $legacy_contract) {
|
||||
if (str_contains($admin_import_sources, $legacy_contract)) {
|
||||
$errors[] = 'Legacy widget import/export contract remains: ' . $legacy_contract;
|
||||
}
|
||||
}
|
||||
|
||||
$pinned_assets = [
|
||||
'DPlayer.min.js' => '361689807fc1e856f868df91036e41195d2c255619bd1c5526849c5ad7491241',
|
||||
'hls.min.js' => 'e876282a26116e323c8ed3e86bed3838a80dbbe3a2faa09f834bee86963ff760',
|
||||
'flv.min.js' => '0668d36757cdc17804d5c0bd6fe8956d76370e73a733bf5bbc0eddbfbca2c6cc',
|
||||
'dash.all.min.js' => '3e753969c16a2a78f420a25d24869f14721eb1d284418f9f22d35a31c3693cd9',
|
||||
'vanilla-tilt.min.js' => 'de6fa8d3f40dbae2726a72f7d1ae46bb0588267af05355bef1d128f737f4a282',
|
||||
];
|
||||
foreach ($pinned_assets as $asset => $hash) {
|
||||
$path = $root . '/assets/widgets/third-party/' . $asset;
|
||||
if (!is_file($path)) {
|
||||
$errors[] = 'Missing pinned widget dependency: ' . $asset;
|
||||
} elseif (hash_file('sha256', $path) !== $hash) {
|
||||
$errors[] = 'Pinned widget dependency changed: ' . $asset;
|
||||
}
|
||||
}
|
||||
if (!is_file($root . '/assets/widgets/third-party/THIRD_PARTY.md')) {
|
||||
$errors[] = 'Missing widget dependency license manifest.';
|
||||
}
|
||||
|
||||
$posts = $registry['posts'];
|
||||
$normalized = $posts->normalize([
|
||||
'title' => '<script>alert(1)</script> 最新课程',
|
||||
@@ -215,4 +308,4 @@ if ($errors) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo "Widget system audit passed: 37 definitions/renderers, frozen baseline, query/REST/assets contracts.\n";
|
||||
echo "Widget system audit passed: 37 widgets, 40 areas, 5 templates, single runtime and pinned assets.\n";
|
||||
|
||||
Reference in New Issue
Block a user