feat: release news and store experience updates
This commit is contained in:
@@ -0,0 +1,520 @@
|
||||
<?php
|
||||
/**
|
||||
* Optional one-click importer for the bundled case portfolio.
|
||||
*
|
||||
* @package Fragrance_Trade
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/** Return the case records available to the optional importer. */
|
||||
function fragrance_trade_case_seeds() {
|
||||
return array(
|
||||
'ford-mondeo-alexander-silver' => array(
|
||||
'title' => __( '福特蒙迪欧|亚历山大银改色膜', 'fragrance-trade' ),
|
||||
'slug' => 'ford-mondeo-alexander-silver',
|
||||
'vehicle' => __( '福特蒙迪欧', 'fragrance-trade' ),
|
||||
'project' => __( '整车改色膜', 'fragrance-trade' ),
|
||||
'color' => __( '亚历山大银', 'fragrance-trade' ),
|
||||
'direction' => __( '哑光金属银、黑银对比', 'fragrance-trade' ),
|
||||
'excerpt' => __( '福特蒙迪欧亚历山大银整车改色,哑光金属银质感搭配黑色车顶与饰件,呈现克制、利落的黑银对比效果。', 'fragrance-trade' ),
|
||||
'intro' => __( '本次施工车型为福特蒙迪欧,车主选择亚历山大银整车改色。银灰色膜面带有细腻的哑光金属质感,与黑色车顶、后视镜、窗框及前后灯组形成清晰的黑银对比。', 'fragrance-trade' ),
|
||||
'effect' => __( '亚历山大银弱化了高亮反射,让蒙迪欧的车身折线在室内灯光和自然光下都更容易被看见。大面积银色保持干净、克制,黑色车顶与饰件则进一步压低视觉重心,让整车轮廓显得更修长。', 'fragrance-trade' ),
|
||||
'details' => __( '施工重点检查了隐藏式门把手、后视镜底座、尾灯边缘、尾翼和车身折角等位置。完成后从正面、侧面和车尾分别复查膜面平整度、拼接位置与边角收口,确保整体颜色连续、车身线条清晰。', 'fragrance-trade' ),
|
||||
'image_count' => 9,
|
||||
'featured_index' => 0,
|
||||
),
|
||||
'porsche-718-liquid-metal-silver' => array(
|
||||
'title' => __( '保时捷 718|液态金属银改色膜', 'fragrance-trade' ),
|
||||
'slug' => 'porsche-718-liquid-metal-silver',
|
||||
'vehicle' => __( '保时捷 718', 'fragrance-trade' ),
|
||||
'project' => __( '整车改色膜', 'fragrance-trade' ),
|
||||
'color' => __( '液态金属银', 'fragrance-trade' ),
|
||||
'direction' => __( '亮面金属银灰、红色软顶对比', 'fragrance-trade' ),
|
||||
'excerpt' => __( '保时捷 718 液态金属银整车改色,以亮面金属银灰强化跑车曲面,并保留红色软顶形成鲜明层次。', 'fragrance-trade' ),
|
||||
'intro' => __( '本次施工车型为保时捷 718,选择液态金属银整车改色。银灰色膜面带有明亮、流动的金属反射,与红色软顶和黑色灯组形成鲜明但克制的颜色层次。', 'fragrance-trade' ),
|
||||
'effect' => __( '液态金属银会随着光线角度呈现由浅银到深灰的变化,能够突出 718 前翼子板、车门和后轮拱的连续曲面。红色软顶保留原有视觉焦点,让整车兼具精致感与运动感。', 'fragrance-trade' ),
|
||||
'details' => __( '施工重点检查前后保险杠曲面、进气口边缘、门把手、后视镜底座、尾翼与软顶交界等位置。交付前分别在正面、侧面和车尾复查膜面连续性与边角收口。', 'fragrance-trade' ),
|
||||
'image_count' => 10,
|
||||
'featured_index' => 0,
|
||||
),
|
||||
'tesla-model-3-highland-alexander-silver' => array(
|
||||
'title' => __( '特斯拉焕新版 Model 3|亚历山大银改色膜', 'fragrance-trade' ),
|
||||
'slug' => 'tesla-model-3-highland-alexander-silver',
|
||||
'vehicle' => __( '特斯拉焕新版 Model 3', 'fragrance-trade' ),
|
||||
'project' => __( '整车改色膜', 'fragrance-trade' ),
|
||||
'color' => __( '亚历山大银', 'fragrance-trade' ),
|
||||
'direction' => __( '哑光金属银、黑色玻璃与轮毂对比', 'fragrance-trade' ),
|
||||
'excerpt' => __( '特斯拉焕新版 Model 3 亚历山大银整车改色,以细腻哑光金属质感呈现更简洁的黑银对比。', 'fragrance-trade' ),
|
||||
'intro' => __( '本次施工车型为特斯拉焕新版 Model 3,选择亚历山大银整车改色。低反光的银色膜面与黑色玻璃、门把手、饰件和轮毂组合,延续车辆简洁、科技感明确的外观语言。', 'fragrance-trade' ),
|
||||
'effect' => __( '亚历山大银降低了车身大面积高光反射,让焕新版 Model 3 的前脸、肩线与溜背轮廓显得更干净。不同光线下,膜面会在冷银与浅灰之间变化,整体观感克制而利落。', 'fragrance-trade' ),
|
||||
'details' => __( '施工重点覆盖无框车门边缘、隐藏式门把手、后视镜底座、前后灯组与保险杠曲面。完成后检查各覆盖面颜色一致性,并确认门把手和车门开合区域收口平整。', 'fragrance-trade' ),
|
||||
'image_count' => 9,
|
||||
'featured_index' => 0,
|
||||
),
|
||||
'byd-han-matte-blue-gold-floating-roof' => array(
|
||||
'title' => __( '比亚迪汉|远峰蓝魅金哑面+悬浮顶', 'fragrance-trade' ),
|
||||
'slug' => 'byd-han-matte-blue-gold-floating-roof',
|
||||
'vehicle' => __( '比亚迪汉', 'fragrance-trade' ),
|
||||
'project' => __( '整车哑面改色膜+悬浮顶', 'fragrance-trade' ),
|
||||
'color' => __( '远峰蓝魅金(哑面)', 'fragrance-trade' ),
|
||||
'direction' => __( '低饱和蓝金变色、哑面质感、黑色悬浮顶', 'fragrance-trade' ),
|
||||
'excerpt' => __( '比亚迪汉远峰蓝魅金哑面整车改色,并搭配黑色悬浮顶,在不同光线下呈现低饱和蓝金变化。', 'fragrance-trade' ),
|
||||
'intro' => __( '本次施工车型为比亚迪汉,选择远峰蓝魅金哑面改色,并搭配黑色悬浮顶。膜面在银灰基调中带有轻微蓝金变化,车顶与窗框的黑色区域则让车身形成清晰的上下分层。', 'fragrance-trade' ),
|
||||
'effect' => __( '哑面效果降低了直接反射,远峰蓝魅金在不同角度和灯光下呈现偏冷银、浅蓝与柔和金色变化。黑色悬浮顶进一步拉长侧面视觉比例,让比亚迪汉的车身姿态更低、更完整。', 'fragrance-trade' ),
|
||||
'details' => __( '施工重点处理悬浮顶边界、A/B/C 柱、后视镜、门把手、尾灯和车身腰线等位置。交付前复查黑色车顶与车身改色膜的边界是否连续,并确认哑面膜无明显压痕或高光点。', 'fragrance-trade' ),
|
||||
'image_count' => 8,
|
||||
'featured_index' => 4,
|
||||
),
|
||||
'chery-arrizo-alexander-silver' => array(
|
||||
'title' => __( '奇瑞艾瑞泽|亚历山大银改色膜', 'fragrance-trade' ),
|
||||
'slug' => 'chery-arrizo-alexander-silver',
|
||||
'vehicle' => __( '奇瑞艾瑞泽', 'fragrance-trade' ),
|
||||
'project' => __( '整车改色膜', 'fragrance-trade' ),
|
||||
'color' => __( '亚历山大银', 'fragrance-trade' ),
|
||||
'direction' => __( '哑光金属银、黑色格栅与灯组对比', 'fragrance-trade' ),
|
||||
'excerpt' => __( '奇瑞艾瑞泽亚历山大银整车改色,以细腻哑光金属银突出车身折线与前脸黑色细节。', 'fragrance-trade' ),
|
||||
'intro' => __( '本次施工车型为奇瑞艾瑞泽,选择亚历山大银整车改色。银色哑光膜面弱化反射,同时保留金属颗粒感,与黑色进气格栅、灯组和车窗区域形成简洁对比。', 'fragrance-trade' ),
|
||||
'effect' => __( '亚历山大银让艾瑞泽的前脸折线、车门腰线和车尾层次更容易被看见。整体颜色接近低饱和银灰,不会掩盖原有造型,适合希望外观焕新但仍保持稳重观感的方案。', 'fragrance-trade' ),
|
||||
'details' => __( '施工重点检查前脸饰条、后视镜、门把手、车顶鲨鱼鳍、尾灯边缘与保险杠转角。交付前从不同光线方向复查膜面色差、平整度和细节收口。', 'fragrance-trade' ),
|
||||
'image_count' => 9,
|
||||
'featured_index' => 0,
|
||||
),
|
||||
'changan-uni-v-gt-silver' => array(
|
||||
'title' => __( '长安 UNI-V|GT 银改色膜', 'fragrance-trade' ),
|
||||
'slug' => 'changan-uni-v-gt-silver',
|
||||
'vehicle' => __( '长安 UNI-V', 'fragrance-trade' ),
|
||||
'project' => __( '整车改色膜', 'fragrance-trade' ),
|
||||
'color' => __( 'GT 银', 'fragrance-trade' ),
|
||||
'direction' => __( '亮面金属银、黑色车顶与运动套件对比', 'fragrance-trade' ),
|
||||
'excerpt' => __( '长安 UNI-V GT 银整车改色,利用亮面金属银与黑色车顶、尾翼和运动饰件强化低趴姿态。', 'fragrance-trade' ),
|
||||
'intro' => __( '本次施工车型为长安 UNI-V,选择 GT 银整车改色。亮面银色膜面能够清晰表现车身折线,与黑色车顶、后视镜、窗框和运动套件形成更直接的银黑对比。', 'fragrance-trade' ),
|
||||
'effect' => __( 'GT 银在室内灯光下呈现干净的金属高光,能够强化 UNI-V 的溜背线条、宽体感和低趴姿态。黑色车顶与尾翼保留原有运动气质,使整体效果更利落。', 'fragrance-trade' ),
|
||||
'details' => __( '施工重点处理无边框车门区域、隐藏式门把手、后视镜底座、前后保险杠折角、尾灯与升降尾翼周边。车辆交付前同时检查外观覆盖面与开合部件的边缘收口。', 'fragrance-trade' ),
|
||||
'image_count' => 12,
|
||||
'featured_index' => 3,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/** Find a case previously created by this importer. */
|
||||
function fragrance_trade_find_seeded_case( $seed_key ) {
|
||||
$ids = get_posts(
|
||||
array(
|
||||
'post_type' => 'case',
|
||||
'post_status' => fragrance_trade_seed_post_statuses(),
|
||||
'posts_per_page' => 1,
|
||||
'fields' => 'ids',
|
||||
'meta_key' => '_fragrance_case_seed_key',
|
||||
'meta_value' => $seed_key,
|
||||
'no_found_rows' => true,
|
||||
)
|
||||
);
|
||||
|
||||
return $ids ? (int) $ids[0] : 0;
|
||||
}
|
||||
|
||||
/** Find a case with the conventional seed slug without changing it. */
|
||||
function fragrance_trade_find_case_seed_slug( $slug ) {
|
||||
$posts = get_posts(
|
||||
array(
|
||||
'post_type' => 'case',
|
||||
'post_status' => fragrance_trade_seed_post_statuses(),
|
||||
'name' => $slug,
|
||||
'posts_per_page' => 1,
|
||||
'no_found_rows' => true,
|
||||
)
|
||||
);
|
||||
|
||||
return $posts ? (int) $posts[0]->ID : 0;
|
||||
}
|
||||
|
||||
/** Find one media item already copied for a seed image. */
|
||||
function fragrance_trade_find_case_seed_attachment( $image_key ) {
|
||||
$ids = get_posts(
|
||||
array(
|
||||
'post_type' => 'attachment',
|
||||
'post_status' => 'inherit',
|
||||
'posts_per_page' => 1,
|
||||
'fields' => 'ids',
|
||||
'meta_key' => '_fragrance_case_seed_image',
|
||||
'meta_value' => $image_key,
|
||||
'no_found_rows' => true,
|
||||
)
|
||||
);
|
||||
|
||||
return $ids ? (int) $ids[0] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy one bundled seed image into the WordPress media library.
|
||||
*
|
||||
* @param int $case_id Parent case post ID.
|
||||
* @param string $seed_key Stable case seed key.
|
||||
* @param array $seed Seed record.
|
||||
* @param int $index Zero-based image index.
|
||||
* @return int|WP_Error
|
||||
*/
|
||||
function fragrance_trade_import_case_seed_image( $case_id, $seed_key, $seed, $index ) {
|
||||
$image_key = $seed_key . ':' . $index;
|
||||
$existing = fragrance_trade_find_case_seed_attachment( $image_key );
|
||||
if ( $existing ) {
|
||||
if ( (int) wp_get_post_parent_id( $existing ) !== (int) $case_id ) {
|
||||
wp_update_post(
|
||||
array(
|
||||
'ID' => $existing,
|
||||
'post_parent' => $case_id,
|
||||
)
|
||||
);
|
||||
}
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$number = $index + 1;
|
||||
$source_file = sprintf(
|
||||
'%1$s/assets/images/cases/%2$s/%3$02d.jpg',
|
||||
get_template_directory(),
|
||||
$seed['slug'],
|
||||
$number
|
||||
);
|
||||
|
||||
if ( ! is_readable( $source_file ) ) {
|
||||
return new WP_Error(
|
||||
'fragrance_case_seed_image_missing',
|
||||
sprintf(
|
||||
/* translators: 1: case title, 2: image number. */
|
||||
__( '案例“%1$s”的第 %2$d 张初始化图片不存在。', 'fragrance-trade' ),
|
||||
$seed['title'],
|
||||
$number
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$image_bytes = file_get_contents( $source_file );
|
||||
if ( false === $image_bytes ) {
|
||||
return new WP_Error(
|
||||
'fragrance_case_seed_image_unreadable',
|
||||
sprintf(
|
||||
/* translators: 1: case title, 2: image number. */
|
||||
__( '无法读取案例“%1$s”的第 %2$d 张初始化图片。', 'fragrance-trade' ),
|
||||
$seed['title'],
|
||||
$number
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$filename = sprintf( '%1$s-%2$02d.jpg', $seed['slug'], $number );
|
||||
$upload = wp_upload_bits( $filename, null, $image_bytes );
|
||||
unset( $image_bytes );
|
||||
|
||||
if ( ! empty( $upload['error'] ) ) {
|
||||
return new WP_Error( 'fragrance_case_seed_upload_failed', $upload['error'] );
|
||||
}
|
||||
|
||||
$attachment_id = wp_insert_attachment(
|
||||
array(
|
||||
'post_mime_type' => 'image/jpeg',
|
||||
'post_title' => sprintf(
|
||||
/* translators: 1: vehicle name, 2: color name, 3: image number. */
|
||||
__( '%1$s %2$s施工实拍图 %3$d', 'fragrance-trade' ),
|
||||
$seed['vehicle'],
|
||||
$seed['color'],
|
||||
$number
|
||||
),
|
||||
'post_status' => 'inherit',
|
||||
),
|
||||
$upload['file'],
|
||||
$case_id,
|
||||
true
|
||||
);
|
||||
|
||||
if ( is_wp_error( $attachment_id ) ) {
|
||||
wp_delete_file( $upload['file'] );
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
$metadata = wp_generate_attachment_metadata( $attachment_id, $upload['file'] );
|
||||
if ( $metadata ) {
|
||||
wp_update_attachment_metadata( $attachment_id, $metadata );
|
||||
}
|
||||
|
||||
update_post_meta( $attachment_id, '_fragrance_case_seed_image', $image_key );
|
||||
update_post_meta(
|
||||
$attachment_id,
|
||||
'_wp_attachment_image_alt',
|
||||
sprintf(
|
||||
/* translators: 1: vehicle name, 2: color name, 3: image number. */
|
||||
__( '%1$s%2$s施工实拍图 %3$d', 'fragrance-trade' ),
|
||||
$seed['vehicle'],
|
||||
$seed['color'],
|
||||
$number
|
||||
)
|
||||
);
|
||||
|
||||
return (int) $attachment_id;
|
||||
}
|
||||
|
||||
/** Build the block-editor content for an imported case. */
|
||||
function fragrance_trade_build_case_seed_content( $seed, $attachment_ids ) {
|
||||
$list = sprintf(
|
||||
'<ul class="wp-block-list"><li><strong>%1$s</strong>%2$s</li><li><strong>%3$s</strong>%4$s</li><li><strong>%5$s</strong>%6$s</li><li><strong>%7$s</strong>%8$s</li></ul>',
|
||||
esc_html__( '车型:', 'fragrance-trade' ),
|
||||
esc_html( $seed['vehicle'] ),
|
||||
esc_html__( '施工项目:', 'fragrance-trade' ),
|
||||
esc_html( $seed['project'] ),
|
||||
esc_html__( '颜色:', 'fragrance-trade' ),
|
||||
esc_html( $seed['color'] ),
|
||||
esc_html__( '外观方向:', 'fragrance-trade' ),
|
||||
esc_html( $seed['direction'] )
|
||||
);
|
||||
|
||||
$gallery = '';
|
||||
foreach ( $attachment_ids as $attachment_id ) {
|
||||
$full_url = wp_get_attachment_url( $attachment_id );
|
||||
$image = wp_get_attachment_image( $attachment_id, 'large' );
|
||||
if ( ! $full_url || ! $image ) {
|
||||
continue;
|
||||
}
|
||||
$gallery .= sprintf(
|
||||
'<!-- wp:image {"id":%1$d,"sizeSlug":"large","linkDestination":"media"} --><figure class="wp-block-image size-large"><a href="%2$s">%3$s</a></figure><!-- /wp:image -->',
|
||||
$attachment_id,
|
||||
esc_url( $full_url ),
|
||||
$image
|
||||
);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<!-- wp:paragraph --><p>%1$s</p><!-- /wp:paragraph -->' .
|
||||
'<!-- wp:heading --><h2 class="wp-block-heading">%2$s</h2><!-- /wp:heading -->' .
|
||||
'<!-- wp:list -->%3$s<!-- /wp:list -->' .
|
||||
'<!-- wp:heading --><h2 class="wp-block-heading">%4$s</h2><!-- /wp:heading -->' .
|
||||
'<!-- wp:paragraph --><p>%5$s</p><!-- /wp:paragraph -->' .
|
||||
'<!-- wp:gallery {"linkTo":"media","sizeSlug":"large"} --><figure class="wp-block-gallery has-nested-images columns-2 is-cropped">%6$s</figure><!-- /wp:gallery -->' .
|
||||
'<!-- wp:heading --><h2 class="wp-block-heading">%7$s</h2><!-- /wp:heading -->' .
|
||||
'<!-- wp:paragraph --><p>%8$s</p><!-- /wp:paragraph -->' .
|
||||
'<!-- wp:paragraph --><p><em>%9$s</em></p><!-- /wp:paragraph -->',
|
||||
esc_html( $seed['intro'] ),
|
||||
esc_html__( '项目概览', 'fragrance-trade' ),
|
||||
$list,
|
||||
esc_html__( '整体效果', 'fragrance-trade' ),
|
||||
esc_html( $seed['effect'] ),
|
||||
$gallery,
|
||||
esc_html__( '细节与收口', 'fragrance-trade' ),
|
||||
esc_html( $seed['details'] ),
|
||||
esc_html__( '提示:实际颜色会受到环境光线、屏幕显示和拍摄设备影响,到店选色请以实物色卡与门店样板为准。', 'fragrance-trade' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import every bundled case without duplicating or overwriting existing work.
|
||||
*
|
||||
* @return array{created:int,existing:int,errors:string[]}
|
||||
*/
|
||||
function fragrance_trade_import_case_seeds() {
|
||||
$result = array(
|
||||
'created' => 0,
|
||||
'existing' => 0,
|
||||
'errors' => array(),
|
||||
);
|
||||
|
||||
$term_name = __( '改色膜', 'fragrance-trade' );
|
||||
$term = term_exists( $term_name, 'case_type' );
|
||||
if ( ! $term ) {
|
||||
$term = wp_insert_term( $term_name, 'case_type' );
|
||||
}
|
||||
if ( is_wp_error( $term ) ) {
|
||||
$result['errors'][] = $term->get_error_message();
|
||||
return $result;
|
||||
}
|
||||
$term_id = (int) ( is_array( $term ) ? $term['term_id'] : $term );
|
||||
|
||||
foreach ( fragrance_trade_case_seeds() as $seed_key => $seed ) {
|
||||
$case_id = fragrance_trade_find_seeded_case( $seed_key );
|
||||
if ( $case_id && 'publish' === get_post_status( $case_id ) ) {
|
||||
++$result['existing'];
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
$case_id
|
||||
&& (
|
||||
'draft' !== get_post_status( $case_id )
|
||||
|| 'importing' !== get_post_meta( $case_id, '_fragrance_case_seed_state', true )
|
||||
)
|
||||
) {
|
||||
++$result['existing'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $case_id ) {
|
||||
$slug_match = fragrance_trade_find_case_seed_slug( $seed['slug'] );
|
||||
if ( $slug_match ) {
|
||||
++$result['existing'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$case_id = wp_insert_post(
|
||||
array(
|
||||
'post_type' => 'case',
|
||||
'post_name' => $seed['slug'],
|
||||
'post_title' => $seed['title'],
|
||||
'post_excerpt' => $seed['excerpt'],
|
||||
'post_status' => 'draft',
|
||||
),
|
||||
true
|
||||
);
|
||||
if ( is_wp_error( $case_id ) ) {
|
||||
$result['errors'][] = sprintf(
|
||||
/* translators: 1: case title, 2: error message. */
|
||||
__( '无法创建案例“%1$s”:%2$s', 'fragrance-trade' ),
|
||||
$seed['title'],
|
||||
$case_id->get_error_message()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
update_post_meta( $case_id, '_fragrance_case_seed_key', $seed_key );
|
||||
update_post_meta( $case_id, '_fragrance_case_seed_state', 'importing' );
|
||||
}
|
||||
|
||||
$attachment_ids = array();
|
||||
$case_errors = array();
|
||||
for ( $index = 0; $index < $seed['image_count']; ++$index ) {
|
||||
$attachment_id = fragrance_trade_import_case_seed_image( $case_id, $seed_key, $seed, $index );
|
||||
if ( is_wp_error( $attachment_id ) ) {
|
||||
$case_errors[] = $attachment_id->get_error_message();
|
||||
continue;
|
||||
}
|
||||
$attachment_ids[] = $attachment_id;
|
||||
}
|
||||
|
||||
if ( $case_errors || count( $attachment_ids ) !== (int) $seed['image_count'] ) {
|
||||
$result['errors'] = array_merge( $result['errors'], $case_errors );
|
||||
continue;
|
||||
}
|
||||
|
||||
$terms_set = wp_set_object_terms( $case_id, array( $term_id ), 'case_type', false );
|
||||
if ( is_wp_error( $terms_set ) ) {
|
||||
$result['errors'][] = $terms_set->get_error_message();
|
||||
continue;
|
||||
}
|
||||
set_post_thumbnail( $case_id, $attachment_ids[ $seed['featured_index'] ] );
|
||||
|
||||
$updated = wp_update_post(
|
||||
array(
|
||||
'ID' => $case_id,
|
||||
'post_title' => $seed['title'],
|
||||
'post_name' => $seed['slug'],
|
||||
'post_excerpt' => $seed['excerpt'],
|
||||
'post_content' => fragrance_trade_build_case_seed_content( $seed, $attachment_ids ),
|
||||
'post_status' => 'publish',
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
if ( is_wp_error( $updated ) ) {
|
||||
$result['errors'][] = sprintf(
|
||||
/* translators: 1: case title, 2: error message. */
|
||||
__( '无法发布案例“%1$s”:%2$s', 'fragrance-trade' ),
|
||||
$seed['title'],
|
||||
$updated->get_error_message()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
delete_post_meta( $case_id, '_fragrance_case_seed_state' );
|
||||
++$result['created'];
|
||||
}
|
||||
|
||||
$result['errors'] = array_values( array_unique( $result['errors'] ) );
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** Add the bundled-content importer below Appearance for administrators. */
|
||||
function fragrance_trade_register_case_seed_page() {
|
||||
add_theme_page(
|
||||
__( '初始化内容', 'fragrance-trade' ),
|
||||
__( '初始化内容', 'fragrance-trade' ),
|
||||
'edit_theme_options',
|
||||
'fragrance-case-import',
|
||||
'fragrance_trade_render_case_seed_page'
|
||||
);
|
||||
}
|
||||
add_action( 'admin_menu', 'fragrance_trade_register_case_seed_page' );
|
||||
|
||||
/** Render the one-click service and case importer. */
|
||||
function fragrance_trade_render_case_seed_page() {
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transient_key = 'fragrance_trade_case_import_result_' . get_current_user_id();
|
||||
$result = get_transient( $transient_key );
|
||||
if ( false !== $result ) {
|
||||
delete_transient( $transient_key );
|
||||
}
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php esc_html_e( '初始化服务与案例', 'fragrance-trade' ); ?></h1>
|
||||
<p><?php esc_html_e( '将主题内置的 5 个产品服务、6 篇汽车改色案例和 62 张图片复制到当前 WordPress 站点。已有同名内容不会被覆盖,重复执行不会产生重复内容。', 'fragrance-trade' ); ?></p>
|
||||
|
||||
<?php if ( is_array( $result ) ) : ?>
|
||||
<?php $notice_class = empty( $result['errors'] ) ? 'notice-success' : 'notice-warning'; ?>
|
||||
<div class="notice <?php echo esc_attr( $notice_class ); ?> is-dismissible">
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: 1: created service count, 2: existing service count, 3: created case count, 4: existing case count. */
|
||||
esc_html__( '初始化完成:服务新增 %1$d 个、已有 %2$d 个;案例新增 %3$d 篇、已有 %4$d 篇。', 'fragrance-trade' ),
|
||||
(int) $result['services']['created'],
|
||||
(int) $result['services']['existing'],
|
||||
(int) $result['cases']['created'],
|
||||
(int) $result['cases']['existing']
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php if ( ! empty( $result['errors'] ) ) : ?>
|
||||
<ul>
|
||||
<?php foreach ( $result['errors'] as $error ) : ?>
|
||||
<li><?php echo esc_html( $error ); ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
|
||||
<input type="hidden" name="action" value="fragrance_trade_import_case_seeds">
|
||||
<?php wp_nonce_field( 'fragrance_trade_import_case_seeds' ); ?>
|
||||
<?php submit_button( __( '一键初始化服务与案例', 'fragrance-trade' ), 'primary', 'submit', false ); ?>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/** Handle the bundled-content importer form submission. */
|
||||
function fragrance_trade_handle_case_seed_import() {
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
wp_die( esc_html__( '您没有权限初始化案例。', 'fragrance-trade' ) );
|
||||
}
|
||||
|
||||
check_admin_referer( 'fragrance_trade_import_case_seeds' );
|
||||
|
||||
$services = fragrance_trade_import_product_service_seeds();
|
||||
$cases = fragrance_trade_import_case_seeds();
|
||||
$result = array(
|
||||
'services' => $services,
|
||||
'cases' => $cases,
|
||||
'errors' => array_values( array_unique( array_merge( $services['errors'], $cases['errors'] ) ) ),
|
||||
);
|
||||
set_transient(
|
||||
'fragrance_trade_case_import_result_' . get_current_user_id(),
|
||||
$result,
|
||||
5 * MINUTE_IN_SECONDS
|
||||
);
|
||||
|
||||
wp_safe_redirect( admin_url( 'themes.php?page=fragrance-case-import' ) );
|
||||
exit;
|
||||
}
|
||||
add_action( 'admin_post_fragrance_trade_import_case_seeds', 'fragrance_trade_handle_case_seed_import' );
|
||||
+67
-2
@@ -345,9 +345,63 @@ function fragrance_trade_create_required_pages( &$errors ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preserve an existing posts page or create the conventional news page.
|
||||
*
|
||||
* @param string[] $errors Setup errors collected by the caller.
|
||||
* @return array{id:int,changed:bool}
|
||||
*/
|
||||
function fragrance_trade_ensure_news_page( &$errors ) {
|
||||
$result = array( 'id' => 0, 'changed' => false );
|
||||
$current_page_id = absint( get_option( 'page_for_posts', 0 ) );
|
||||
$current_page = $current_page_id ? get_post( $current_page_id ) : null;
|
||||
|
||||
if ( $current_page && 'page' === $current_page->post_type ) {
|
||||
$result['id'] = $current_page_id;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$news_page = fragrance_trade_find_required_page( 'news' );
|
||||
if ( ! $news_page ) {
|
||||
$news_page_id = wp_insert_post(
|
||||
array(
|
||||
'post_type' => 'page',
|
||||
'post_name' => 'news',
|
||||
'post_title' => __( '新闻资讯', 'fragrance-trade' ),
|
||||
'post_status' => 'publish',
|
||||
),
|
||||
true
|
||||
);
|
||||
if ( is_wp_error( $news_page_id ) ) {
|
||||
$errors[] = sprintf(
|
||||
/* translators: %s: error message. */
|
||||
__( '无法创建新闻资讯页面:%s', 'fragrance-trade' ),
|
||||
$news_page_id->get_error_message()
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
|
||||
$news_page = get_post( $news_page_id );
|
||||
$result['changed'] = true;
|
||||
}
|
||||
|
||||
$news_page_id = (int) $news_page->ID;
|
||||
if ( $current_page_id !== $news_page_id ) {
|
||||
update_option( 'page_for_posts', $news_page_id );
|
||||
if ( $news_page_id !== absint( get_option( 'page_for_posts', 0 ) ) ) {
|
||||
$errors[] = __( '无法将新闻资讯页面设置为 WordPress 文章页。', 'fragrance-trade' );
|
||||
return $result;
|
||||
}
|
||||
$result['changed'] = true;
|
||||
}
|
||||
|
||||
$result['id'] = $news_page_id;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/** Versioned and retryable site setup. */
|
||||
function fragrance_trade_maybe_setup_site() {
|
||||
$target_version = 3;
|
||||
$target_version = 4;
|
||||
if ( (int) get_option( 'fragrance_trade_schema_version', 0 ) >= $target_version ) {
|
||||
return;
|
||||
}
|
||||
@@ -356,12 +410,13 @@ function fragrance_trade_maybe_setup_site() {
|
||||
$seed_changed = fragrance_trade_create_seed_services( $errors );
|
||||
$copy_changed = fragrance_trade_migrate_seed_service_copy( $errors );
|
||||
$page_result = fragrance_trade_create_required_pages( $errors );
|
||||
$news_result = fragrance_trade_ensure_news_page( $errors );
|
||||
|
||||
if ( ! empty( $page_result['pages']['home'] ) ) {
|
||||
update_option( 'page_on_front', $page_result['pages']['home'] );
|
||||
update_option( 'show_on_front', 'page' );
|
||||
}
|
||||
if ( $seed_changed || $copy_changed || $page_result['changed'] ) {
|
||||
if ( $seed_changed || $copy_changed || $page_result['changed'] || $news_result['changed'] ) {
|
||||
flush_rewrite_rules();
|
||||
}
|
||||
|
||||
@@ -412,6 +467,16 @@ function fragrance_trade_page_status_notice() {
|
||||
$unpublished[] = $page->post_title;
|
||||
}
|
||||
}
|
||||
$posts_page_id = absint( get_option( 'page_for_posts', 0 ) );
|
||||
$posts_page = $posts_page_id ? get_post( $posts_page_id ) : null;
|
||||
if (
|
||||
$posts_page
|
||||
&& 'page' === $posts_page->post_type
|
||||
&& 'publish' !== $posts_page->post_status
|
||||
&& ! in_array( $posts_page->post_title, $unpublished, true )
|
||||
) {
|
||||
$unpublished[] = $posts_page->post_title;
|
||||
}
|
||||
if ( ! $unpublished ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,10 +92,18 @@ function fragrance_trade_customize_register( $wp_customize ) {
|
||||
array( 'youtube_url', 'fragrance_contact_social', __( 'YouTube 链接', 'fragrance-trade' ), 'url' ),
|
||||
array( 'linkedin_url', 'fragrance_contact_social', __( 'LinkedIn 链接', 'fragrance-trade' ), 'url' ),
|
||||
array( 'instagram_social_url', 'fragrance_contact_social', __( 'Instagram 链接', 'fragrance-trade' ), 'url' ),
|
||||
array( 'store_brand', 'fragrance_contact_social', __( '主营品牌', 'fragrance-trade' ), 'text' ),
|
||||
array( 'store_authorization', 'fragrance_contact_social', __( '授权级别', 'fragrance-trade' ), 'text' ),
|
||||
array( 'store_city', 'fragrance_contact_social', __( '所在城市', 'fragrance-trade' ), 'text' ),
|
||||
array( 'store_contact_person', 'fragrance_contact_social', __( '门店联系人', 'fragrance-trade' ), 'text' ),
|
||||
array( 'store_address', 'fragrance_contact_social', __( '门店地址', 'fragrance-trade' ), 'textarea' ),
|
||||
array( 'store_phone', 'fragrance_contact_social', __( '联系电话', 'fragrance-trade' ), 'text' ),
|
||||
array( 'store_hours', 'fragrance_contact_social', __( '营业时间', 'fragrance-trade' ), 'text' ),
|
||||
array( 'store_map_url', 'fragrance_contact_social', __( '地图导航链接', 'fragrance-trade' ), 'url' ),
|
||||
array( 'store_map_lat', 'fragrance_contact_social', __( '百度地图纬度', 'fragrance-trade' ), 'text' ),
|
||||
array( 'store_map_lng', 'fragrance_contact_social', __( '百度地图经度', 'fragrance-trade' ), 'text' ),
|
||||
array( 'icp_number', 'fragrance_contact_social', __( 'ICP备案号', 'fragrance-trade' ), 'text' ),
|
||||
array( 'icp_url', 'fragrance_contact_social', __( 'ICP备案查询链接', 'fragrance-trade' ), 'url' ),
|
||||
array( 'footer_text', 'fragrance_contact_social', __( '页脚定位文案', 'fragrance-trade' ), 'text' ),
|
||||
);
|
||||
|
||||
|
||||
+14
-6
@@ -18,8 +18,8 @@ function fragrance_trade_defaults() {
|
||||
|
||||
$defaults = array(
|
||||
'b2b_hero_eyebrow' => __( '需求沟通 · 方案确认 · 施工交付', 'fragrance-trade' ),
|
||||
'b2b_hero_title' => __( 'xxx店铺名字', 'fragrance-trade' ),
|
||||
'b2b_hero_text' => __( 'xxx地址', 'fragrance-trade' ),
|
||||
'b2b_hero_title' => __( '康得新合肥新创贴膜中心(官方授权店)', 'fragrance-trade' ),
|
||||
'b2b_hero_text' => __( '康得新 KDX 官方授权至尊服务店,位于合肥市瑶海区铜陵北路高架桥出口与铜陵北路辅路交叉口东北140米。', 'fragrance-trade' ),
|
||||
'b2b_hero_primary_label' => __( '联系门店', 'fragrance-trade' ),
|
||||
'b2b_hero_primary_url' => '/contact/',
|
||||
'b2b_hero_secondary_label' => __( '了解服务项目', 'fragrance-trade' ),
|
||||
@@ -85,11 +85,19 @@ function fragrance_trade_defaults() {
|
||||
'youtube_url' => '',
|
||||
'linkedin_url' => '',
|
||||
'instagram_social_url' => '',
|
||||
'store_address' => '',
|
||||
'store_phone' => __( 'xxx电话', 'fragrance-trade' ),
|
||||
'store_hours' => '',
|
||||
'store_brand' => __( '康得新 KDX', 'fragrance-trade' ),
|
||||
'store_authorization' => __( '官方授权至尊服务店', 'fragrance-trade' ),
|
||||
'store_city' => __( '合肥市', 'fragrance-trade' ),
|
||||
'store_contact_person' => __( '贾文浩', 'fragrance-trade' ),
|
||||
'store_address' => __( '合肥市瑶海区铜陵北路高架桥出口与铜陵北路辅路交叉口东北140米', 'fragrance-trade' ),
|
||||
'store_phone' => '18655174646',
|
||||
'store_hours' => __( '09:00–22:30', 'fragrance-trade' ),
|
||||
'store_map_url' => '',
|
||||
'footer_text' => __( '专注汽车贴膜方案沟通、施工交付与日常护理说明。', 'fragrance-trade' ),
|
||||
'store_map_lat' => '31.907786',
|
||||
'store_map_lng' => '117.336666',
|
||||
'icp_number' => '',
|
||||
'icp_url' => 'https://beian.miit.gov.cn/',
|
||||
'footer_text' => __( '康得新 KDX 官方授权至尊服务店,提供隐形车衣、改色膜与汽车隔热膜服务。', 'fragrance-trade' ),
|
||||
);
|
||||
|
||||
return $defaults;
|
||||
|
||||
+121
-1
@@ -32,6 +32,74 @@ function fragrance_trade_image_uri( $setting, $fallback_filename ) {
|
||||
return $image ? $image : fragrance_trade_asset_uri( 'images/' . $fallback_filename );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the horizontal image used by service cards and carousels.
|
||||
*
|
||||
* Product seeds use a dedicated landscape cover while their featured image
|
||||
* remains the complete parameter poster shown on the service detail page.
|
||||
*
|
||||
* @param int $post_id Service post ID.
|
||||
* @param string $fallback_filename Asset path below assets/images/.
|
||||
* @return string
|
||||
*/
|
||||
function fragrance_trade_service_card_image( $post_id, $fallback_filename = 'products/placeholder-01.svg' ) {
|
||||
$post_id = absint( $post_id );
|
||||
$image_attr = array(
|
||||
'class' => 'img-fluid',
|
||||
'loading' => 'lazy',
|
||||
'decoding' => 'async',
|
||||
);
|
||||
$cover_id = absint( get_post_meta( $post_id, '_fragrance_service_cover_id', true ) );
|
||||
|
||||
if ( $cover_id ) {
|
||||
$image = wp_get_attachment_image( $cover_id, 'large', false, $image_attr );
|
||||
if ( $image ) {
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
|
||||
$cover_file = (string) get_post_meta( $post_id, '_fragrance_service_cover_file', true );
|
||||
if ( ! $cover_file && function_exists( 'fragrance_trade_product_service_seeds' ) ) {
|
||||
$seeds = fragrance_trade_product_service_seeds();
|
||||
$seed_key = (string) get_post_meta( $post_id, '_fragrance_product_seed_key', true );
|
||||
|
||||
if ( $seed_key && isset( $seeds[ $seed_key ]['cover'] ) ) {
|
||||
$cover_file = $seeds[ $seed_key ]['cover'];
|
||||
} else {
|
||||
$post_slug = (string) get_post_field( 'post_name', $post_id );
|
||||
foreach ( $seeds as $seed ) {
|
||||
if ( $post_slug === $seed['slug'] && ! empty( $seed['cover'] ) ) {
|
||||
$cover_file = $seed['cover'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
$cover_file
|
||||
&& preg_match( '#^[a-zA-Z0-9/_-]+\.(?:jpe?g|png|webp)$#', $cover_file )
|
||||
&& is_readable( get_template_directory() . '/assets/images/services/' . $cover_file )
|
||||
) {
|
||||
return sprintf(
|
||||
'<img src="%1$s" alt="%2$s" class="img-fluid" width="1448" height="1086" loading="lazy" decoding="async">',
|
||||
esc_url( fragrance_trade_asset_uri( 'images/services/' . $cover_file ) ),
|
||||
esc_attr( get_the_title( $post_id ) )
|
||||
);
|
||||
}
|
||||
|
||||
if ( has_post_thumbnail( $post_id ) ) {
|
||||
return (string) get_the_post_thumbnail( $post_id, 'fragrance-capability', $image_attr );
|
||||
}
|
||||
|
||||
$legacy_image = get_post_meta( $post_id, '_service_image', true );
|
||||
return sprintf(
|
||||
'<img src="%1$s" alt="%2$s" class="img-fluid" loading="lazy" decoding="async">',
|
||||
esc_url( $legacy_image ? $legacy_image : fragrance_trade_asset_uri( 'images/' . ltrim( $fallback_filename, '/' ) ) ),
|
||||
esc_attr( get_the_title( $post_id ) )
|
||||
);
|
||||
}
|
||||
|
||||
function fragrance_trade_show_section( $setting ) {
|
||||
return (bool) fragrance_trade_get_mod( $setting, true );
|
||||
}
|
||||
@@ -56,11 +124,36 @@ function fragrance_trade_get_inquiry_url( $project = '' ) {
|
||||
return 'mailto:' . antispambot( fragrance_trade_inquiry_email() ) . '?subject=' . rawurlencode( __( '汽车贴膜服务咨询', 'fragrance-trade' ) ) . '&body=' . rawurlencode( $message );
|
||||
}
|
||||
|
||||
/** Return the configured WordPress posts-page URL with a stable fresh-site fallback. */
|
||||
function fragrance_trade_news_url() {
|
||||
$posts_page_id = absint( get_option( 'page_for_posts', 0 ) );
|
||||
$posts_page = $posts_page_id ? get_post( $posts_page_id ) : null;
|
||||
if ( $posts_page && 'page' === $posts_page->post_type ) {
|
||||
$url = get_permalink( $posts_page_id );
|
||||
if ( $url ) {
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
return home_url( '/news/' );
|
||||
}
|
||||
|
||||
/** Keep news grids aligned without changing the site's global reading option. */
|
||||
function fragrance_trade_news_posts_per_page( $query ) {
|
||||
if ( is_admin() || ! $query->is_main_query() || $query->is_feed() ) {
|
||||
return;
|
||||
}
|
||||
if ( $query->is_home() || $query->is_category() || $query->is_tag() || $query->is_date() || $query->is_author() ) {
|
||||
$query->set( 'posts_per_page', 9 );
|
||||
}
|
||||
}
|
||||
add_action( 'pre_get_posts', 'fragrance_trade_news_posts_per_page' );
|
||||
|
||||
function fragrance_trade_primary_menu_fallback() {
|
||||
$links = array(
|
||||
array( 'label' => __( '首页', 'fragrance-trade' ), 'url' => home_url( '/' ) ),
|
||||
array( 'label' => __( '服务项目', 'fragrance-trade' ), 'url' => get_post_type_archive_link( 'service' ) ?: home_url( '/services/' ) ),
|
||||
array( 'label' => __( '案例作品', 'fragrance-trade' ), 'url' => get_post_type_archive_link( 'case' ) ?: home_url( '/cases/' ) ),
|
||||
array( 'label' => __( '新闻资讯', 'fragrance-trade' ), 'url' => fragrance_trade_news_url() ),
|
||||
array( 'label' => __( '关于门店', 'fragrance-trade' ), 'url' => home_url( '/about/' ) ),
|
||||
array( 'label' => __( '常见问题', 'fragrance-trade' ), 'url' => home_url( '/faq/' ) ),
|
||||
array( 'label' => __( '联系我们', 'fragrance-trade' ), 'url' => home_url( '/contact/' ) ),
|
||||
@@ -102,7 +195,34 @@ add_action(
|
||||
printf(
|
||||
'<div class="notice notice-warning is-dismissible"><p><strong>%s</strong> %s <a href="%s">%s</a></p></div>',
|
||||
esc_html__( '主导航菜单项过少', 'fragrance-trade' ),
|
||||
esc_html__( '手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、关于门店、常见问题、联系我们。', 'fragrance-trade' ),
|
||||
esc_html__( '手机端和桌面端导航目前只显示一个菜单项。请前往后台添加:首页、服务项目、案例作品、新闻资讯、关于门店、常见问题、联系我们。', 'fragrance-trade' ),
|
||||
esc_url( admin_url( 'nav-menus.php' ) ),
|
||||
esc_html__( '编辑菜单', 'fragrance-trade' )
|
||||
);
|
||||
}
|
||||
|
||||
$news_page_id = absint( get_option( 'page_for_posts', 0 ) );
|
||||
$news_page = $news_page_id ? get_post( $news_page_id ) : null;
|
||||
if ( ! $news_page || 'publish' !== $news_page->post_status ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$news_url = untrailingslashit( fragrance_trade_news_url() );
|
||||
$has_news_link = false;
|
||||
foreach ( (array) $items as $item ) {
|
||||
if (
|
||||
( 'page' === $item->object && $news_page_id === (int) $item->object_id )
|
||||
|| $news_url === untrailingslashit( $item->url )
|
||||
) {
|
||||
$has_news_link = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! $has_news_link ) {
|
||||
printf(
|
||||
'<div class="notice notice-warning is-dismissible"><p><strong>%s</strong> %s <a href="%s">%s</a></p></div>',
|
||||
esc_html__( '主导航尚未包含新闻资讯', 'fragrance-trade' ),
|
||||
esc_html__( '主题不会自动修改已分配的菜单,请将 WordPress 文章页添加到“主导航”。', 'fragrance-trade' ),
|
||||
esc_url( admin_url( 'nav-menus.php' ) ),
|
||||
esc_html__( '编辑菜单', 'fragrance-trade' )
|
||||
);
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
<?php
|
||||
/**
|
||||
* Optional one-click importer for the bundled KDX service products.
|
||||
*
|
||||
* @package Fragrance_Trade
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/** Return every post status that may contain an existing optional seed. */
|
||||
function fragrance_trade_seed_post_statuses() {
|
||||
return array( 'publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash' );
|
||||
}
|
||||
|
||||
/** Return the product service records available to the optional importer. */
|
||||
function fragrance_trade_product_service_seeds() {
|
||||
return array(
|
||||
'kdx-dunjia' => array(
|
||||
'title' => __( 'KDX 盾甲隐形车衣', 'fragrance-trade' ),
|
||||
'slug' => 'kdx-dunjia-paint-protection-film',
|
||||
'image' => 'kdx-dunjia.jpg',
|
||||
'cover' => 'covers/kdx-dunjia-cover.jpg',
|
||||
'excerpt' => __( '7.5mil 厚度 · 7 年质保 · 光泽度 150', 'fragrance-trade' ),
|
||||
'summary' => __( '盾甲是一款兼顾车漆保护、亮面效果与日常养护的隐形车衣产品,适合关注基础防护与光泽表现的用车场景。', 'fragrance-trade' ),
|
||||
'specs' => array(
|
||||
__( '产品厚度', 'fragrance-trade' ) => '7.5mil',
|
||||
__( '质保年限', 'fragrance-trade' ) => __( '7 年', 'fragrance-trade' ),
|
||||
__( '光泽度', 'fragrance-trade' ) => '150',
|
||||
__( '拉伸强度', 'fragrance-trade' ) => '18MPa',
|
||||
__( '断裂伸长率', 'fragrance-trade' ) => '380%',
|
||||
__( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
|
||||
__( '水接触角', 'fragrance-trade' ) => '102°',
|
||||
__( '耐粘污性', 'fragrance-trade' ) => __( '良好', 'fragrance-trade' ),
|
||||
__( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
|
||||
),
|
||||
),
|
||||
'kdx-kaijia-plus' => array(
|
||||
'title' => __( 'KDX 铠甲 Plus 隐形车衣', 'fragrance-trade' ),
|
||||
'slug' => 'kdx-kaijia-plus-paint-protection-film',
|
||||
'image' => 'kdx-kaijia-plus.jpg',
|
||||
'cover' => 'covers/kdx-kaijia-plus-cover.jpg',
|
||||
'excerpt' => __( '8.5mil 厚度 · 8 年质保 · 断裂伸长率 460%', 'fragrance-trade' ),
|
||||
'summary' => __( '铠甲 Plus 采用更高的标称厚度和断裂伸长率,适合希望进一步提升车漆覆盖防护与膜面韧性的用车需求。', 'fragrance-trade' ),
|
||||
'specs' => array(
|
||||
__( '产品厚度', 'fragrance-trade' ) => '8.5mil',
|
||||
__( '质保年限', 'fragrance-trade' ) => __( '8 年', 'fragrance-trade' ),
|
||||
__( '光泽度', 'fragrance-trade' ) => '150',
|
||||
__( '拉伸强度', 'fragrance-trade' ) => '23MPa',
|
||||
__( '断裂伸长率', 'fragrance-trade' ) => '460%',
|
||||
__( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
|
||||
__( '水接触角', 'fragrance-trade' ) => '73°',
|
||||
__( '耐粘污性', 'fragrance-trade' ) => __( '良好', 'fragrance-trade' ),
|
||||
__( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
|
||||
),
|
||||
),
|
||||
'kdx-kaijia' => array(
|
||||
'title' => __( 'KDX 铠甲隐形车衣', 'fragrance-trade' ),
|
||||
'slug' => 'kdx-kaijia-paint-protection-film',
|
||||
'image' => 'kdx-kaijia.jpg',
|
||||
'cover' => 'covers/kdx-kaijia-cover.jpg',
|
||||
'excerpt' => __( '7.5mil 厚度 · 7 年质保 · 拉伸强度 25MPa', 'fragrance-trade' ),
|
||||
'summary' => __( '铠甲隐形车衣侧重膜面韧性、亮面效果与基础耐粘污表现,并提供雾度、可见光透射比和剥离力等补充参数。', 'fragrance-trade' ),
|
||||
'specs' => array(
|
||||
__( '产品厚度', 'fragrance-trade' ) => '7.5mil',
|
||||
__( '质保年限', 'fragrance-trade' ) => __( '7 年', 'fragrance-trade' ),
|
||||
__( '光泽度', 'fragrance-trade' ) => '150',
|
||||
__( '拉伸强度', 'fragrance-trade' ) => '25MPa',
|
||||
__( '断裂伸长率', 'fragrance-trade' ) => '430%',
|
||||
__( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
|
||||
__( '水接触角', 'fragrance-trade' ) => '73°',
|
||||
__( '耐粘污性', 'fragrance-trade' ) => __( '三星', 'fragrance-trade' ),
|
||||
__( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
|
||||
__( '雾度', 'fragrance-trade' ) => '0.3%',
|
||||
__( '可见光透射比', 'fragrance-trade' ) => '90%',
|
||||
__( '180°剥离力(30 分钟)', 'fragrance-trade' ) => '1400gf/inch',
|
||||
__( '180°剥离力(2 小时)', 'fragrance-trade' ) => '1800gf/inch',
|
||||
__( '涂层断裂伸长率', 'fragrance-trade' ) => '160%',
|
||||
),
|
||||
),
|
||||
'kdx-dunjia-plus' => array(
|
||||
'title' => __( 'KDX 盾甲 Plus 隐形车衣', 'fragrance-trade' ),
|
||||
'slug' => 'kdx-dunjia-plus-paint-protection-film',
|
||||
'image' => 'kdx-dunjia-plus.jpg',
|
||||
'cover' => 'covers/kdx-dunjia-plus-cover.jpg',
|
||||
'excerpt' => __( '8.5mil 厚度 · 8 年质保 · 水接触角 102°', 'fragrance-trade' ),
|
||||
'summary' => __( '盾甲 Plus 在盾甲产品方向上提升标称厚度与质保年限,兼顾膜面亮度、水接触角和日常车漆保护需求。', 'fragrance-trade' ),
|
||||
'specs' => array(
|
||||
__( '产品厚度', 'fragrance-trade' ) => '8.5mil',
|
||||
__( '质保年限', 'fragrance-trade' ) => __( '8 年', 'fragrance-trade' ),
|
||||
__( '光泽度', 'fragrance-trade' ) => '150',
|
||||
__( '拉伸强度', 'fragrance-trade' ) => '21MPa',
|
||||
__( '断裂伸长率', 'fragrance-trade' ) => '400%',
|
||||
__( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
|
||||
__( '水接触角', 'fragrance-trade' ) => '102°',
|
||||
__( '耐粘污性', 'fragrance-trade' ) => __( '良好', 'fragrance-trade' ),
|
||||
__( '热修复', 'fragrance-trade' ) => __( '60 秒', 'fragrance-trade' ),
|
||||
),
|
||||
),
|
||||
'kdx-jinjia-pro' => array(
|
||||
'title' => __( 'KDX 金甲 PRO 隐形车衣', 'fragrance-trade' ),
|
||||
'slug' => 'kdx-jinjia-pro-paint-protection-film',
|
||||
'image' => 'kdx-jinjia-pro.jpg',
|
||||
'cover' => 'covers/kdx-jinjia-pro-cover.jpg',
|
||||
'excerpt' => __( '7.5mil 厚度 · 8 年质保 · 光泽度 153', 'fragrance-trade' ),
|
||||
'summary' => __( '金甲 PRO 侧重高光泽、耐粘污表现与较长质保周期,适合关注亮面质感和日常清洁便利性的车漆保护方案。', 'fragrance-trade' ),
|
||||
'specs' => array(
|
||||
__( '产品厚度', 'fragrance-trade' ) => '7.5mil',
|
||||
__( '质保年限', 'fragrance-trade' ) => __( '8 年', 'fragrance-trade' ),
|
||||
__( '光泽度', 'fragrance-trade' ) => '153',
|
||||
__( '拉伸强度', 'fragrance-trade' ) => '18MPa',
|
||||
__( '断裂伸长率', 'fragrance-trade' ) => '350%',
|
||||
__( '耐有机溶剂性', 'fragrance-trade' ) => __( '通过', 'fragrance-trade' ),
|
||||
__( '水接触角', 'fragrance-trade' ) => '95°',
|
||||
__( '耐粘污性', 'fragrance-trade' ) => __( '优秀', 'fragrance-trade' ),
|
||||
__( '热修复', 'fragrance-trade' ) => __( '90 秒', 'fragrance-trade' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/** Find a product service previously created by this importer. */
|
||||
function fragrance_trade_find_product_service_seed( $seed_key ) {
|
||||
$ids = get_posts(
|
||||
array(
|
||||
'post_type' => 'service',
|
||||
'post_status' => fragrance_trade_seed_post_statuses(),
|
||||
'posts_per_page' => 1,
|
||||
'fields' => 'ids',
|
||||
'meta_key' => '_fragrance_product_seed_key',
|
||||
'meta_value' => $seed_key,
|
||||
'no_found_rows' => true,
|
||||
)
|
||||
);
|
||||
|
||||
return $ids ? (int) $ids[0] : 0;
|
||||
}
|
||||
|
||||
/** Find a service with the conventional product slug. */
|
||||
function fragrance_trade_find_product_service_slug( $slug ) {
|
||||
$posts = get_posts(
|
||||
array(
|
||||
'post_type' => 'service',
|
||||
'post_status' => fragrance_trade_seed_post_statuses(),
|
||||
'name' => $slug,
|
||||
'posts_per_page' => 1,
|
||||
'no_found_rows' => true,
|
||||
)
|
||||
);
|
||||
|
||||
return $posts ? (int) $posts[0]->ID : 0;
|
||||
}
|
||||
|
||||
/** Find a bundled product image already copied into the media library. */
|
||||
function fragrance_trade_find_product_service_attachment( $seed_key ) {
|
||||
$ids = get_posts(
|
||||
array(
|
||||
'post_type' => 'attachment',
|
||||
'post_status' => 'inherit',
|
||||
'posts_per_page' => 1,
|
||||
'fields' => 'ids',
|
||||
'meta_key' => '_fragrance_product_seed_image',
|
||||
'meta_value' => $seed_key,
|
||||
'no_found_rows' => true,
|
||||
)
|
||||
);
|
||||
|
||||
return $ids ? (int) $ids[0] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy one bundled service image into the WordPress media library.
|
||||
*
|
||||
* @param int $service_id Parent service post ID.
|
||||
* @param string $seed_key Stable service seed key.
|
||||
* @param array $seed Service seed record.
|
||||
* @return int|WP_Error
|
||||
*/
|
||||
function fragrance_trade_import_product_service_image( $service_id, $seed_key, $seed ) {
|
||||
$existing = fragrance_trade_find_product_service_attachment( $seed_key );
|
||||
if ( $existing ) {
|
||||
if ( (int) wp_get_post_parent_id( $existing ) !== (int) $service_id ) {
|
||||
wp_update_post(
|
||||
array(
|
||||
'ID' => $existing,
|
||||
'post_parent' => $service_id,
|
||||
)
|
||||
);
|
||||
}
|
||||
return $existing;
|
||||
}
|
||||
|
||||
$source_file = get_template_directory() . '/assets/images/services/' . $seed['image'];
|
||||
if ( ! is_readable( $source_file ) ) {
|
||||
return new WP_Error(
|
||||
'fragrance_product_seed_image_missing',
|
||||
sprintf(
|
||||
/* translators: %s: service title. */
|
||||
__( '服务“%s”的初始化图片不存在。', 'fragrance-trade' ),
|
||||
$seed['title']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$image_bytes = file_get_contents( $source_file );
|
||||
if ( false === $image_bytes ) {
|
||||
return new WP_Error(
|
||||
'fragrance_product_seed_image_unreadable',
|
||||
sprintf(
|
||||
/* translators: %s: service title. */
|
||||
__( '无法读取服务“%s”的初始化图片。', 'fragrance-trade' ),
|
||||
$seed['title']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$upload = wp_upload_bits( $seed['image'], null, $image_bytes );
|
||||
unset( $image_bytes );
|
||||
if ( ! empty( $upload['error'] ) ) {
|
||||
return new WP_Error( 'fragrance_product_seed_upload_failed', $upload['error'] );
|
||||
}
|
||||
|
||||
$attachment_id = wp_insert_attachment(
|
||||
array(
|
||||
'post_mime_type' => 'image/jpeg',
|
||||
'post_title' => sprintf(
|
||||
/* translators: %s: service title. */
|
||||
__( '%s产品参数图', 'fragrance-trade' ),
|
||||
$seed['title']
|
||||
),
|
||||
'post_status' => 'inherit',
|
||||
),
|
||||
$upload['file'],
|
||||
$service_id,
|
||||
true
|
||||
);
|
||||
|
||||
if ( is_wp_error( $attachment_id ) ) {
|
||||
wp_delete_file( $upload['file'] );
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
$metadata = wp_generate_attachment_metadata( $attachment_id, $upload['file'] );
|
||||
if ( $metadata ) {
|
||||
wp_update_attachment_metadata( $attachment_id, $metadata );
|
||||
}
|
||||
|
||||
update_post_meta( $attachment_id, '_fragrance_product_seed_image', $seed_key );
|
||||
update_post_meta(
|
||||
$attachment_id,
|
||||
'_wp_attachment_image_alt',
|
||||
sprintf(
|
||||
/* translators: %s: service title. */
|
||||
__( '%s产品参数与车型示意图', 'fragrance-trade' ),
|
||||
$seed['title']
|
||||
)
|
||||
);
|
||||
|
||||
return (int) $attachment_id;
|
||||
}
|
||||
|
||||
/** Build block-editor content for a product service. */
|
||||
function fragrance_trade_build_product_service_content( $seed ) {
|
||||
$items = '';
|
||||
foreach ( $seed['specs'] as $label => $value ) {
|
||||
$items .= sprintf(
|
||||
'<li><strong>%1$s:</strong>%2$s</li>',
|
||||
esc_html( $label ),
|
||||
esc_html( $value )
|
||||
);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<!-- wp:paragraph --><p>%1$s</p><!-- /wp:paragraph -->' .
|
||||
'<!-- wp:heading --><h2 class="wp-block-heading">%2$s</h2><!-- /wp:heading -->' .
|
||||
'<!-- wp:list --><ul class="wp-block-list">%3$s</ul><!-- /wp:list -->' .
|
||||
'<!-- wp:paragraph --><p><em>%4$s</em></p><!-- /wp:paragraph -->',
|
||||
esc_html( $seed['summary'] ),
|
||||
esc_html__( '产品参数', 'fragrance-trade' ),
|
||||
$items,
|
||||
esc_html__( '以上参数根据所提供的产品资料整理。实际产品版本、施工范围、价格、质保条件与交付标准请以门店最终确认及正式质保文件为准。', 'fragrance-trade' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import every bundled product service without overwriting existing content.
|
||||
*
|
||||
* @return array{created:int,existing:int,errors:string[]}
|
||||
*/
|
||||
function fragrance_trade_import_product_service_seeds() {
|
||||
$result = array(
|
||||
'created' => 0,
|
||||
'existing' => 0,
|
||||
'errors' => array(),
|
||||
);
|
||||
|
||||
foreach ( fragrance_trade_product_service_seeds() as $seed_key => $seed ) {
|
||||
$service_id = fragrance_trade_find_product_service_seed( $seed_key );
|
||||
if ( $service_id && 'publish' === get_post_status( $service_id ) ) {
|
||||
update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
|
||||
++$result['existing'];
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
$service_id
|
||||
&& (
|
||||
'draft' !== get_post_status( $service_id )
|
||||
|| 'importing' !== get_post_meta( $service_id, '_fragrance_product_seed_state', true )
|
||||
)
|
||||
) {
|
||||
update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
|
||||
++$result['existing'];
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! $service_id ) {
|
||||
if ( fragrance_trade_find_product_service_slug( $seed['slug'] ) ) {
|
||||
++$result['existing'];
|
||||
continue;
|
||||
}
|
||||
|
||||
$service_id = wp_insert_post(
|
||||
array(
|
||||
'post_type' => 'service',
|
||||
'post_name' => $seed['slug'],
|
||||
'post_title' => $seed['title'],
|
||||
'post_excerpt' => $seed['excerpt'],
|
||||
'post_status' => 'draft',
|
||||
),
|
||||
true
|
||||
);
|
||||
if ( is_wp_error( $service_id ) ) {
|
||||
$result['errors'][] = sprintf(
|
||||
/* translators: 1: service title, 2: error message. */
|
||||
__( '无法创建服务“%1$s”:%2$s', 'fragrance-trade' ),
|
||||
$seed['title'],
|
||||
$service_id->get_error_message()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
update_post_meta( $service_id, '_fragrance_product_seed_key', $seed_key );
|
||||
update_post_meta( $service_id, '_fragrance_product_seed_state', 'importing' );
|
||||
update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
|
||||
}
|
||||
|
||||
$attachment_id = fragrance_trade_import_product_service_image( $service_id, $seed_key, $seed );
|
||||
if ( is_wp_error( $attachment_id ) ) {
|
||||
$result['errors'][] = $attachment_id->get_error_message();
|
||||
continue;
|
||||
}
|
||||
|
||||
set_post_thumbnail( $service_id, $attachment_id );
|
||||
$updated = wp_update_post(
|
||||
array(
|
||||
'ID' => $service_id,
|
||||
'post_title' => $seed['title'],
|
||||
'post_name' => $seed['slug'],
|
||||
'post_excerpt' => $seed['excerpt'],
|
||||
'post_content' => fragrance_trade_build_product_service_content( $seed ),
|
||||
'post_status' => 'publish',
|
||||
),
|
||||
true
|
||||
);
|
||||
|
||||
if ( is_wp_error( $updated ) ) {
|
||||
$result['errors'][] = sprintf(
|
||||
/* translators: 1: service title, 2: error message. */
|
||||
__( '无法发布服务“%1$s”:%2$s', 'fragrance-trade' ),
|
||||
$seed['title'],
|
||||
$updated->get_error_message()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
delete_post_meta( $service_id, '_fragrance_product_seed_state' );
|
||||
update_post_meta( $service_id, '_fragrance_service_cover_file', $seed['cover'] );
|
||||
++$result['created'];
|
||||
}
|
||||
|
||||
$result['errors'] = array_values( array_unique( $result['errors'] ) );
|
||||
return $result;
|
||||
}
|
||||
Reference in New Issue
Block a user