Rose Girl Home.
* Version: 1.0
* Requires Plugins: woocommerce
*/
if (!defined(‘ABSPATH’)) exit;

/* ———- 1. Danh sách ô cài đặt: key => [nhãn, kiểu, mặc định] ———- */
function rg_fields() {
$g = [
‘Banner chính’ => [
‘hero_image’ => [‘Ảnh banner (gợi ý 1600×1000)’, ‘image’, ”],
‘hero_kicker’ => [‘Dòng nhỏ phía trên’, ‘text’, ‘PROFESSIONAL LASH SUPPLIES’],
‘hero_title’ => [‘Tiêu đề’, ‘text’, ‘Volume fans for lash artists who love detail’],
‘hero_text’ => [‘Mô tả’, ‘text’, ‘300 lash styles, medical grade glue, and wholesale prices. Always in stock.’],
‘hero_b1’ => [‘Nút 1 (chữ)’, ‘text’, ‘Shop eyelashes’],
‘hero_u1’ => [‘Nút 1 (link)’, ‘text’, ‘/danh-muc/eyelash/’],
‘hero_b2’ => [‘Nút 2 (chữ)’, ‘text’, ‘View combo deals’],
‘hero_u2’ => [‘Nút 2 (link)’, ‘text’, ‘/danh-muc/combo/’],
],
‘Sản phẩm và danh mục (tự lấy từ website)’ => [
‘cat_slugs’ => [‘Danh mục hiển thị (slug, cách nhau dấu phẩy)’, ‘text’, ‘loose-promade-fan,loose-handmade-fan,ultra-speed-promade-fans,wispy-promade-fans,eyelashestray,glues’],
‘best_title’=> [‘Tiêu đề khối bán chạy’, ‘text’, ‘Best sellers’],
‘best_cat’ => [‘Chỉ lấy từ danh mục (slug, để trống = tất cả)’, ‘text’, ”],
‘best_n’ => [‘Số sản phẩm bán chạy’, ‘text’, ‘8’],
‘rows’ => [‘Các hàng sản phẩm theo danh mục. Mỗi dòng: Tiêu đề|slug danh mục|số sản phẩm’, ‘textarea’,
“Loose promade, 500 fans|loose-fan-500|4\nMix 3 in 1, 750 fans|mix-promade-750-fans|4\nMix 4 in 1, 1000 fans|mix-4-in-1-ultra-speed-promade-1000-fans|4″],
],
‘Banner combo’ => [
‘combo_image’ => [‘Ảnh banner combo (gợi ý 560×300)’, ‘image’, ”],
‘combo_title’ => [‘Tiêu đề’, ‘text’, ‘Deal combo: save up to 36%’],
‘combo_text’ => [‘Mô tả’, ‘text’, ‘Mix lengths, mix curls, one box. Built for busy lash studios.’],
‘combo_b’ => [‘Nút (chữ)’, ‘text’, ‘Shop combos’],
‘combo_u’ => [‘Nút (link)’, ‘text’, ‘/danh-muc/combo/’],
],
];
$feat = [[‘Volume eyelash extension fans’,’Glamorous yet natural’,’/danh-muc/eyelash/’],[‘Mink lashes’,’Lightweight, comfortable band’,’/danh-muc/eyelash/eyelashestray/mink-lashes/’],[‘Extension glue’,’Strong bond, long retention’,’/danh-muc/glues/’]];
foreach ($feat as $i => $f) { $n = $i + 1;
$g[‘Thẻ nổi bật ‘ . $n] = [“feat{$n}_image” => [‘Ảnh (gợi ý 800×450)’, ‘image’, ”], “feat{$n}_title” => [‘Tiêu đề’, ‘text’, $f[0]], “feat{$n}_sub” => [‘Mô tả ngắn’, ‘text’, $f[1]], “feat{$n}_url” => [‘Link’, ‘text’, $f[2]]];
}
$g[‘Rewards, đánh giá, Instagram’] = [
‘rw_image’ => [‘Ảnh Rewards (gợi ý 800×600)’, ‘image’, ”],
‘rw_title’ => [‘Tiêu đề Rewards’, ‘text’, ‘Rose Girl Rewards’],
‘rw_text’ => [‘Mô tả Rewards’, ‘text’, ‘Earn points on every order, get wholesale prices, and join The Artist Directory to be found by new clients.’],
‘rw_url’ => [‘Link nút Join now’, ‘text’, ‘/my-account/’],
‘reviews’ => [‘Đánh giá. Mỗi dòng: Nội dung|Người viết’, ‘textarea’, “Fans hold their shape and the curl stays perfect for weeks.|Lash studio owner\nGlue bonds strong and lasts. Shipping arrived right on time.|Freelance lash tech\nBest prices for 1000-fan boxes, and the mix packs save me time.|Salon buyer”],
‘blog_n’ => [‘Số bài blog mới nhất’, ‘text’, ‘3’],
‘insta’ => [‘Ảnh Instagram (mỗi dòng một link ảnh, tối đa 6)’, ‘images’, ”],
‘insta_u’ => [‘Link Instagram’, ‘text’, ‘https://www.instagram.com/rosegirllash/’],
];
$show = [‘trust’=>’Dải cam kết’,’categories’=>’Danh mục’,’best’=>’Bán chạy’,’rows’=>’Hàng sản phẩm theo danh mục’,’combo’=>’Banner combo’,’features’=>’3 thẻ nổi bật’,’fans’=>’Choose your fan’,’rewards’=>’Rewards’,’reviews’=>’Đánh giá’,’blog’=>’Blog’,’instagram’=>’Instagram’,’stats’=>’Số liệu’];
foreach ($show as $k => $l) $g[‘Bật/tắt khối’][“show_$k”] = [$l, ‘check’, 1];
return $g;
}
function rg_o() {
static $o;
if (!$o) { $d = []; foreach (rg_fields() as $grp) foreach ($grp as $k => $v) $d[$k] = $v[2]; $o = wp_parse_args(get_option(‘rg_home’, []), $d); }
return $o;
}

/* ———- 2. Trang cài đặt ———- */
add_action(‘admin_menu’, function () { add_options_page(‘Rose Girl Home’, ‘Rose Girl Home’, ‘manage_options’, ‘rg-home’, ‘rg_admin’); });
add_action(‘admin_init’, function () {
register_setting(‘rg_home_g’, ‘rg_home’, [‘sanitize_callback’ => function ($in) {
$out = [];
foreach (rg_fields() as $grp) foreach ($grp as $k => $v) {
$val = isset($in[$k]) ? $in[$k] : ”;
$out[$k] = $v[1] === ‘check’ ? (empty($val) ? 0 : 1) : ($v[1] === ‘image’ ? esc_url_raw($val) : ($v[1] === ‘text’ ? sanitize_text_field($val) : sanitize_textarea_field($val)));
}
return $out;
}]);
});
add_action(‘admin_enqueue_scripts’, function ($h) { if ($h === ‘settings_page_rg-home’) wp_enqueue_media(); });
function rg_admin() {
$o = rg_o();
echo ‘

Rose Girl Home

Chèn shortcode [rosegirl_home] vào trang chủ. Sản phẩm, danh mục, bài viết được lấy tự động từ website.

‘;
settings_fields(‘rg_home_g’);
foreach (rg_fields() as $title => $grp) {
echo ‘

‘ . esc_html($title) . ‘

‘;
foreach ($grp as $k => $v) {
$n = “rg_home[$k]”; $val = $o[$k];
echo ‘

‘;
}
echo ‘

‘;
if ($v[1] === ‘check’) echo ‘‘;
elseif ($v[1] === ‘textarea’ || $v[1] === ‘images’) echo ‘‘ . ($v[1] === ‘images’ ? ‘‘ : ”);
else echo ‘‘ . ($v[1] === ‘image’ ? ‘‘ . ($val ? ‘ ‘ : ”) : ”);
echo ‘

‘;
}
submit_button();
echo ‘

‘;
}

/* ———- 3. Hàm hỗ trợ ———- */
function rg_url($u) { return (strpos($u, ‘/’) === 0) ? home_url($u) : $u; }
function rg_slot($src, $cls, $icon) {
return ‘

‘ . ($src ? ‘‘ : ‘‘) . ‘

‘;
}
function rg_products($slug, $n, $retry = true) {
$a = [‘post_type’ => ‘product’, ‘post_status’ => ‘publish’, ‘posts_per_page’ => max(1, (int)$n), ‘no_found_rows’ => true, ‘order’ => ‘DESC’,
‘tax_query’ => [[‘taxonomy’ => ‘product_visibility’, ‘field’ => ‘name’, ‘terms’ => [‘exclude-from-catalog’], ‘operator’ => ‘NOT IN’]]];
if ($retry) { $a[‘meta_key’] = ‘total_sales’; $a[‘orderby’] = ‘meta_value_num’; } else { $a[‘orderby’] = ‘date’; }
if ($slug) $a[‘tax_query’][] = [‘taxonomy’ => ‘product_cat’, ‘field’ => ‘slug’, ‘terms’ => array_map(‘trim’, explode(‘,’, $slug))];
$out = [];
foreach (get_posts($a) as $po) { $p = wc_get_product($po); if ($p) $out[] = $p; }
return (!$out && $retry) ? rg_products($slug, $n, false) : $out;
}
function rg_pct($p) {
if (!$p->is_on_sale()) return 0;
if ($p->is_type(‘variable’)) {
$v = $p->get_variation_prices(true); $best = 0;
foreach ($v[‘price’] as $id => $pr) { $r = (float)$v[‘regular_price’][$id]; if ($r > 0 && $pr < $r) $best = max($best, round(($r - $pr) / $r * 100)); } return (int)$best; } $r = (float)$p->get_regular_price(); $s = (float)$p->get_sale_price();
return ($r > 0 && $s > 0 && $s < $r) ? (int)round(($r - $s) / $r * 100) : 0; } function rg_card($p) { global $product; $product = $p; $pct = rg_pct($p); echo '

‘;
}
function rg_head($t, $link = ”, $sub = ”) {
echo ‘

‘ . ($sub ? ‘

‘ . esc_html($sub) . ‘

‘ : ”);
}
function rg_css() { return <<<'CSS' .rg-home{--rose:#993556;--plum:#72243E;--ink:#4B1528;--blush:#FBEAF0;--pink:#F4C0D1;--cream:#FFFAF7;--accent:#D4537E;width:100vw;position:relative;left:50%;margin-left:-50vw;background:var(--cream);color:var(--ink);font:14px/1.6 Poppins,sans-serif} .rg-home *{box-sizing:border-box}.rg-home a{color:inherit;text-decoration:none} .rg-home h1,.rg-home h2{font-family:'Playfair Display',serif;font-weight:500;margin:0;line-height:1.2;color:var(--ink)} .rg-w{max-width:1200px;margin:0 auto;padding:0 20px}.rg-s{padding:30px 0} .rg-hd{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:16px}.rg-hd h2{font-size:24px} .rg-sub{color:var(--rose);margin:-8px 0 16px}.rg-more{color:var(--rose);font-size:13px} .rg-btn{display:inline-block;padding:11px 20px;border-radius:6px;font-weight:500;border:1px solid var(--plum)}.rg-b1{background:var(--plum);color:var(--cream)!important}.rg-b2{color:var(--plum)} .rg-g{display:grid;gap:16px}.rg-g3{grid-template-columns:repeat(3,minmax(0,1fr))}.rg-g4{grid-template-columns:repeat(4,minmax(0,1fr))}.rg-g6{grid-template-columns:repeat(6,minmax(0,1fr));gap:10px} .rg-box,.rg-card{background:#fff;border:1px solid var(--pink);border-radius:10px;overflow:hidden;display:block} .rg-in{padding:12px 14px}.rg-in b{font-weight:500} .rg-slot{position:relative;overflow:hidden;background:var(--blush);display:flex;align-items:center;justify-content:center;color:var(--rose);font-size:34px;width:100%} .rg-slot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover} .rg-sq{aspect-ratio:1/1}.rg-wide{aspect-ratio:16/9}.rg-cat{aspect-ratio:4/1}.rg-hero{aspect-ratio:16/10} .rg-img{display:block;position:relative;aspect-ratio:1/1;background:var(--blush)}.rg-img img{width:100%;height:100%;object-fit:cover;display:block;margin:0} .rg-tag{position:absolute;top:8px;left:8px;z-index:2;background:var(--plum);color:var(--cream);font-size:12px;padding:1px 8px;border-radius:4px} .rg-name{display:block;font-size:13px;min-height:40px;line-height:1.5}.rg-price{font-weight:500;margin:4px 0 10px}.rg-price del{color:var(--rose);font-size:12px;font-weight:400;margin-right:4px}.rg-price ins{text-decoration:none} .rg-card .button{display:block!important;text-align:center;border:1px solid var(--plum)!important;background:transparent!important;color:var(--plum)!important;border-radius:6px!important;padding:7px!important;font-size:13px!important;font-weight:500!important;margin:0!important} .rg-card .added_to_cart{display:block;text-align:center;font-size:12px;margin-top:6px} .rg-trust{background:#fff;border-bottom:1px solid var(--pink)}.rg-trust .rg-w{display:grid;grid-template-columns:repeat(4,1fr);text-align:center;padding-top:16px;padding-bottom:16px}.rg-trust i{font-size:22px;color:var(--rose);display:block} .rg-hero-s{background:var(--blush)}.rg-hero-s .rg-w{display:grid;grid-template-columns:1.1fr 1fr;gap:24px;align-items:center;padding-top:32px;padding-bottom:32px} .rg-hero-s h1{font-size:44px;margin:8px 0 12px}.rg-btns{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px} .rg-combo{background:var(--plum);color:var(--blush);border-radius:14px;display:grid;grid-template-columns:1fr 280px;overflow:hidden;align-items:stretch} .rg-combo .tx{padding:26px 30px}.rg-combo h2{color:var(--cream);font-size:28px}.rg-combo .rg-btn{background:var(--cream);color:var(--plum);margin-top:14px}.rg-combo .rg-slot{min-height:150px;height:100%;background:#8a3350;color:var(--pink)} .rg-fan{border-radius:10px;padding:14px 6px;text-align:center}.rg-fan b{display:block;font-family:'Playfair Display',serif;font-size:24px;font-weight:500} .rg-rw{display:grid;grid-template-columns:1fr 1fr;background:#fff;border:1px solid var(--pink);border-radius:12px;overflow:hidden}.rg-rw .rg-slot{height:100%;min-height:220px}.rg-rw .tx{padding:28px} .rg-stars{color:var(--accent);font-size:17px}.rg-stats{background:var(--blush)}.rg-stats .rg-g{padding:24px 0}.rg-num{font-family:'Playfair Display',serif;font-size:26px;color:var(--rose)} @media(max-width:800px){.rg-g4{grid-template-columns:repeat(2,minmax(0,1fr))}.rg-g3{grid-template-columns:1fr}.rg-g6{grid-template-columns:repeat(3,minmax(0,1fr))}.rg-hero-s .rg-w,.rg-combo,.rg-rw{grid-template-columns:1fr}.rg-hero-s h1{font-size:32px}.rg-trust .rg-w{grid-template-columns:repeat(2,1fr);gap:10px}.rg-cat{aspect-ratio:3/1}} CSS; }/* ---------- 4. Shortcode ---------- */ add_shortcode('rosegirl_home', function () { if (!function_exists('wc_get_product')) return '

Cần bật WooCommerce.

‘;
$o = rg_o(); $on = function ($k) use ($o) { return !empty($o[“show_$k”]); };
wp_enqueue_style(‘rg-fonts’, ‘https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500&family=Poppins:wght@400;500&display=swap’);
wp_enqueue_style(‘rg-icons’, ‘https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3.19.0/dist/tabler-icons.min.css’);
$shop = wc_get_page_permalink(‘shop’);
ob_start();
echo ‘

‘;

// Banner chính
echo ‘

‘ . esc_html($o[‘hero_kicker’]) . ‘

‘ . esc_html($o[‘hero_title’]) . ‘

‘ . esc_html($o[‘hero_text’]) . ‘

‘ . rg_slot($o[‘hero_image’], ‘rg-hero’, ‘eye’) . ‘

‘;

if ($on(‘trust’)) { echo ‘

‘; foreach ([[‘certificate’, ‘Original product’], [‘lock’, ‘Secure payment’], [‘refresh’, ‘7 days return’], [‘truck-delivery’, ‘Free ship from $200’]] as $t) echo ‘

‘ . $t[1] . ‘

‘; echo ‘

‘; }

// Danh mục thật
if ($on(‘categories’)) {
echo ‘

‘; rg_head(‘Shop by category’, ”, ‘Find the right lash in two clicks’); echo ‘

‘;
foreach (array_filter(array_map(‘trim’, explode(‘,’, $o[‘cat_slugs’]))) as $slug) {
$t = get_term_by(‘slug’, $slug, ‘product_cat’); if (!$t || is_wp_error($t)) continue;
$img = wp_get_attachment_image_url((int)get_term_meta($t->term_id, ‘thumbnail_id’, true), ‘large’);
echo ‘‘ . rg_slot($img, ‘rg-cat’, ‘eye’) . ‘

‘ . esc_html($t->name) . ‘

‘;
}
echo ‘

‘;
}

// Bán chạy
if ($on(‘best’)) {
echo ‘

‘; rg_head($o[‘best_title’], $shop); echo ‘

‘;
foreach (rg_products($o[‘best_cat’], $o[‘best_n’]) as $p) rg_card($p);
echo ‘

‘;
}

// Banner combo
if ($on(‘combo’)) echo ‘

‘ . esc_html($o[‘combo_title’]) . ‘

‘ . esc_html($o[‘combo_text’]) . ‘

‘ . esc_html($o[‘combo_b’]) . ‘

‘ . rg_slot($o[‘combo_image’], ”, ‘gift’) . ‘

‘;

// Các hàng sản phẩm theo danh mục
if ($on(‘rows’)) foreach (array_filter(array_map(‘trim’, explode(“\n”, $o[‘rows’]))) as $line) {
$r = array_map(‘trim’, explode(‘|’, $line)); if (count($r) < 2) continue; $items = rg_products($r[1], isset($r[2]) ? $r[2] : 4); if (!$items) continue; $t = get_term_by('slug', $r[1], 'product_cat'); echo '

‘; rg_head($r[0], ($t && !is_wp_error($t)) ? get_term_link($t) : $shop); echo ‘

‘;
foreach ($items as $p) rg_card($p);
echo ‘

‘;
}

// 3 thẻ nổi bật
if ($on(‘features’)) { echo ‘

‘; }

// Choose your fan
if ($on(‘fans’)) { echo ‘

‘; rg_head(‘Choose your fan’, ”, ‘From natural to mega volume, pick by density’); echo ‘

‘;
foreach ([[‘3D’, ‘Natural’, ‘#FBEAF0’, ‘#993556’], [‘5D’, ‘Soft volume’, ‘#F4C0D1’, ‘#72243E’], [‘8D’, ‘Classic volume’, ‘#F4C0D1’, ‘#72243E’], [’10D’, ‘Full’, ‘#ED93B1’, ‘#4B1528′], [’12D’, ‘Mega’, ‘#ED93B1’, ‘#4B1528′], [’16D’, ‘Ultra mega’, ‘#D4537E’, ‘#FFFAF7’]] as $f) echo ‘

‘ . $f[0] . ‘‘ . $f[1] . ‘

‘;
echo ‘

‘; }

// Rewards
if ($on(‘rewards’)) echo ‘

‘ . rg_slot($o[‘rw_image’], ”, ‘users’) . ‘

FOR PROFESSIONALS

‘ . esc_html($o[‘rw_title’]) . ‘

‘ . esc_html($o[‘rw_text’]) . ‘

‘;

// Đánh giá
if ($on(‘reviews’)) { echo ‘

‘; rg_head(‘Loved by lash artists’, ”, ‘Real reviews from real studios’); echo ‘

‘;
foreach (array_filter(array_map(‘trim’, explode(“\n”, $o[‘reviews’]))) as $line) { $r = explode(‘|’, $line, 2); echo ‘

‘ . str_repeat(‘‘, 5) . ‘

‘ . esc_html($r[0]) . ‘

‘ . esc_html(isset($r[1]) ? $r[1] : ”) . ‘

‘; }
echo ‘

‘; }

// Blog thật
if ($on(‘blog’)) { $posts = get_posts([‘numberposts’ => max(1, (int)$o[‘blog_n’]), ‘post_status’ => ‘publish’]);
if ($posts) { echo ‘

‘; } }

// Instagram
if ($on(‘instagram’)) { echo ‘

‘; rg_head(‘Follow @rosegirllash’, ”, ‘Sets, tips, and new arrivals on Instagram’); echo ‘

‘;
$imgs = array_slice(array_pad(array_values(array_filter(array_map(‘trim’, explode(“\n”, $o[‘insta’])))), 6, ”), 0, 6);
foreach ($imgs as $s) echo ‘‘ . rg_slot($s, ‘rg-sq’, ‘brand-instagram’) . ‘‘;
echo ‘

‘; }

// Số liệu
if ($on(‘stats’)) { echo ‘

‘;
foreach ([[‘300+’, ‘lash styles in stock’], [‘9/10’, ‘customer satisfaction’], [‘Vegan’, ‘cruelty-free, latex-free options’], [‘Wholesale’, ‘prices and training’]] as $s) echo ‘

‘ . $s[0] . ‘

‘ . $s[1] . ‘

‘;
echo ‘

‘; }

echo ‘

‘;
return ob_get_clean();
});