Changelog iga-core
0.5.33 - 2026-10-17
/chon-menh/: khi mọi loại đá đã chọn, trang mở ra hiện đủ 62 loại (lọc "Tất cả") để nhân viên xem lại và sửa; còn loại chưa chọn thì vẫn chỉ hiện loại đó.
0.5.32 - 2026-10-16
data/menh.json+data/stones.json: Thạch anh (chưa rõ loại), Thạch anh xanh, Thạch anh tóc (chưa rõ màu) gán đủ 5 mệnh theo nhân viên tư vấn (không rõ màu thì chọn đủ).
0.5.31 - 2026-10-16
/chon-menh/: mặc định chỉ hiện loại đá chưa chọn (nút lọc "Chưa chọn" đứng đầu), chọn xong loại nào thì loại đó tự ẩn; hết thì báo đã chọn xong.
0.5.30 - 2026-10-16
data/menh.json+data/stones.json: áp lựa chọn của nhân viên tư vấn (ảnh chụp trang /chon-menh/ 23:12) cho 23 loại đá khác bảng màu: Topaz (Kim, Thủy); Thạch anh tóc vàng, Thạch anh vàng (Kim, Thủy, Thổ); Thạch anh mắt chim ưng, Đá giông bão (Mộc, Thủy); Đá mắt rồng, Fluorit (Mộc, Hỏa, Thổ); Ngọc đế quang (Mộc, Hỏa); Pyrite (Kim, Thủy); đủ 5 mệnh: Opal, Zircon, Beryl, Ametrine, Thạch anh tóc tam tài, ngũ sắc, Super 23, cầu vồng, Super Seven, Chalcedony, Băng ngọc thủy tảo, Amazonite, Mica, Mix.
0.5.29 - 2026-10-16
/chon-menh/: bấm chọn mệnh là lưu ngay (ghi chú tự lưu sau 1,2 giây), không còn bước Xác nhận dễ bị quên; thiếu tên thì báo rõ và tự lưu khi nhập tên; lựa chọn chưa lưu được giữ trong trình duyệt (localStorage) và tự gửi khi mở lại trang.
0.5.28 - 2026-10-16
data/menh.json+data/stones.json: Thạch anh ưu linh, Thạch anh super seven gán đủ 5 mệnh (không kỵ mệnh, theo cửa hàng).
0.5.27 - 2026-10-16
data/menh.json+data/stones.json: Ruby, Sapphire, Kim cương, Cẩm thạch, Hổ phách, Tourmaline, Thạch anh ưu linh gán đủ 5 mệnh (trườngmenh+moi_menh: true) theo cửa hàng: đá quý không kỵ mệnh. Ghi đè thắng cả màu trong tên sản phẩm (vd Sapphire vàng).
0.5.26 - 2026-10-16
- Trang nội bộ
/chon-menh/(lớpTools\Menh_Vote,assets/js/chon-menh.js,assets/css/chon-menh.css): nhân viên tư vấn chọn mệnh hợp cho từng loại đá trongdata/menh.json, có ô ghi chú và tên người chọn. Lưu quaGET/POST /wp-json/iga/v1/chon-menh, mỗi loại đá một optioniga_chon_menh__<slug>(autoload no, giữ 10 bản cũ). Chỉ bật khiWP_ENVIRONMENT_TYPElà staging hoặcIGA_CHON_MENH= true; trang noindex, không cache.
0.5.25 - 2026-10-16
Data\Menh::for_product: áp dụng ghi đèmenhcủa loại đá khi gán cho từng sản phẩm (trước đó chỉstone_menhđọc trường này nên 0.5.24 không đổi sản phẩm nào); ghi đè thắng cả màu viết trong tên sản phẩm.
0.5.24 - 2026-10-16
data/menh.json: loại đá có thể ghi đè mệnh bằng trườngmenh(Data\Menh::stone_menh); cẩm thạch chỉ gán Mộc (bỏ Hỏa) theo ý kiến nhân viên tư vấn.
0.5.23 - 2026-10-16
- Lệnh mới
wp iga menh(lớpCLI\Menh_Command, logic thuần ởData\Menh, bảng ởdata/menh.json): gán lại thuộc tính "Mệnh hợp" (pa_menh) theo MÀU CHỦ ĐẠO của loại đá. Đá màu hành E hợp mệnh E và hành mà E sinh ra (Ruby đỏ: Hỏa, Thổ; thạch anh tóc vàng: Kim, Thổ; Sapphire xanh dương/đen: Mộc, Thủy). Loại đá nhiều màu đọc màu viết ngay sau tên đá trong tên sản phẩm; không có thì lấy mệnh ghi rõ trong mô tả shop; không có nữa thì để trống (không đoán).apply --dry-run [--report=<file>]thống kê và liệt kê sản phẩm có mô tả shop ghi mệnh khác bảng mới;apply --backup-dir=<dir>sao lưurows.jsonl+rows.sha256(đọc ngược kiểm) rồi ghiterm_relationshipstrong một giao dịch, tính lại số đếm term, reindex bộ lọc đúng các sản phẩm đổi, đổi phiên bản cache lọc, đọc lại so khớp;rollback --dir=<dir> [--force];tablein bảng. Chạy lại không đổi gì thêm.
data/stones.json: cộtmenhcủa 62 loại đá đổi theomenh.json(32 loại đổi;menh_sourcechỉ cònrulehoặcnone; nhiều màu để trống thay vì ghi đủ 5 mệnh), có kiểm thử so khớp (tests/phpunit/Data/MenhTest.php).Schema\Product_Schema: bỏhasMerchantReturnPolicy(MerchantReturnPolicy đổi trả 3 ngày) vàshippingDetails(OfferShippingDetails giao hàng miễn phí 0 VND) khỏi mọi Offer của Product/ProductGroup. Shop không cam kết đổi trả, và prod chỉ miễn phí giao hàng khi khách chuyển khoản trước nên schema không được hứa thay shop. Offer không có giá vẫn bị bỏ như cũ.
0.5.22 - 2026-10-16
Content\Desc_Fix(sapo củawp iga desc-fix) bỏ hai chỗ tự suy: (1) "tự nhiên" chỉ ghi khi TÊN sản phẩm hoặc một dòng RIÊNG của mô tả ngắn nói là tự nhiên/thiên nhiên (dòng cam kết chung của shop bắt đầu bằng dấu tick hoặc có chữ "cam kết" nằm ở hầu hết mô tả ngắn nên không còn tính; hàm mớiexcerpt_product_text()); (2) xuất xứ chỉ ghi "có xuất xứ từ X" đúng dữ liệu (ưu tiên mục cụ thể nhất như "Phan Thiết (Bình Thuận)"), không còn "khai thác tại" vì prod chỉ có nhãn "Xuất xứ". Kiểm thử cập nhật + thêmtest_sapo_natural_only_from_product_own_text.CLI\Lp5_Hero(trang tổng /bo-suu-tap/): câu giới thiệu 3 nhóm lấy nguyên văn prod hoặc chỉ liệt kê tên mẫu ("Phật giáo mật tông đưa ra thuyết 8 vị Bản Tôn chủ quản 12 con giáp"; bỏ "được thờ và đeo nhiều nhất" và "mang may mắn, tài lộc và bình an" vì prod không có).
0.5.21 - 2026-10-16
wp iga desc-fixv2 (cấu trúc mô tả chuẩn hơn, chạy đúng trên nội dung GỐC): SAPO dựng từ dữ liệu thật của sản phẩm (tên không "#mã" in đậm, loại sản phẩm, hình tượng, loại đá, xuất xứ, nhóm đá + một câu giới thiệu dễ hiểu từ mô tả ngắn); H2 MỚI đặt tên cho cụm đoạn mở đầu cũ ("Ý nghĩa {hình tượng}", "Ý nghĩa Phật bản mệnh ...", "Ý nghĩa đá ...", "Giới thiệu {tên}"); heading phần A (hình tượng) là H3 dưới H2 mở đầu, heading mở phần B (loại đá) là H2 và các mục sau là H3/H4; không có phần B thì heading cũ là H3 (giữ H2 khi từ 3 chủ đề lớn cùng bậc). Mô tả đã mở đầu bằng sapo thì bỏ qua (idempotent).- Tuỳ chọn
--original-from=<thư mục sao lưu>(chỉ cùng--dry-run): xem trước trên nội dung gốc lấy từrows.jsonlcủa một lần chạy trước mà không phải hoàn tác DB. Content\Headings::retag()/step()tách ra để lập bậc heading theo luật riêng; kiểm thửtests/phpunit/Content/DescFixTest.phpviết lại cho v2.
0.5.20 - 2026-10-16
- Lệnh mới
wp iga desc-fix(lớpCLI\Desc_Fix_Command, logic thuần ởContent\Desc_Fix): chuẩn hoá mô tả sản phẩm (post_content) thẳng trong DB.- Bỏ dòng tiêu đề lặp tên sản phẩm ở đầu (mọi h1 chữ thuần; h2/h3 chỉ khi lặp tên; tiêu đề mục như "Ý nghĩa ..." hoặc "... là gì?" được giữ).
- Dựng sapo: khối kế tiếp là
<blockquote>thì chuyển thành các<p>(p đầuclass="sapo"); là<p>/chữ trần từ 60 ký tự thì gắnclass="sapo"; còn lại lấy dòng giới thiệu đầu tiên (không phải "Nhãn: giá trị", không phải dòng cam kết có dấu tick, từ 40 ký tự) của mô tả ngắn làm<p class="sapo">. - Heading: h1 thành h2, cấp cao nhất là h2, không nhảy cấp (h3 mở đầu thành h2, h4 sau h2 thành h3).
- Lệnh mới
wp iga headings-fix [--type=page,post](lớpCLI\Headings_Fix_Command, logic thuần ởContent\Headings): cùng luật heading cho trang và bài viết đang xuất bản. Trang dựng bằng khối: đổi đồng bộleveltrong chú thíchwp:headingvà thẻ HTML, kiểm bằngparse_blockstrước/sau (cùng số khối, bậc khớp thẻ). Bỏ qua trang WooCommerce; heading rỗng hoặc chỉ ảnh không đổi (chỉ ghi chú). - Cả hai lệnh dùng chung
CLI\Content_Fix_Base:--dry-run(thống kê + mẫu trước/sau), sao lưurows.jsonlngoài webroot (kiểm đọc ngược + băm) trước khi ghi, ghi bằng$wpdb->updatetrong một giao dịch rồi đọc lại so băm,clean_post_cachetừng ID,--rollback=<thư mục>(kiểm băm từng hàng), chạy lại không đổi gì thêm. Mỗi hàng qua bước kiểm chữ trước/sau; hàng không đạt bị bỏ nguyên. - Kiểm thử:
tests/phpunit/Content/HeadingsTest.php,DescFixTest.php.
0.5.19 - 2026-10-15 (lô G1)
- Lệnh mới
wp iga image-swap(lớpCLI\Image_Swap_Command, logic thuần ởMedia\Image_Swap): thay ảnh lấy từ mạng bằng ảnh AI trongpost_contentvàpost_excerptcủa bài/sản phẩm.import --dir=<thư mục>: nhập ảnh mới vào Thư viện bằngwp media import(tiêu đề, alt tiếng Việt, chú thích "Ảnh AI tạo (G1)"), gắn meta_iga_g1_job; chạy lại không nhập trùng.swap [--dry-run|--apply --backup-dir=<ngoài webroot>]: đổi URL cỡ gốc và mọi cỡ-WxH(src, srcset, dạng mã hoá phần trăm), lớpwp-image-<id>và"id":<id>của khốiwp:image. Banner dùngproductstrong manifest để chỉ đổi ở đúng nhóm sản phẩm. Sao lưurows.jsonl(kiểm đọc ngược + băm), ghi trong một giao dịch, đọc lại so băm rồi mới COMMIT; không xoá ảnh cũ, không đổipost_modified.rollback --dir=<thư mục sao lưu> [--force]: khôi phục và kiểm băm từng hàng.- Job có
supersedes(bản làm lại) thay luôn ảnh AI của bản trước; job cófeatured_postsđổi cả ảnh đại diện (_thumbnail_id) của các bài đó (sao lưuthumbs.json, hoàn tác kiểm giá trị). - Danh sách job:
data/image-swap/g1.json(cộng dồn các đợt). Kiểm thử:tests/phpunit/Media/ImageSwapTest.php.
0.5.18 - 2026-10-15
- Sửa nút "Xem thêm" không bấm được ở nhóm có ô tìm (nút lấy nhầm dòng "Không có lựa chọn phù hợp" làm danh sách).
0.5.17 - 2026-10-15
- Mức giá: nhãn "nghìn" đổi thành "k" (
data/price-buckets.json); không hiện lựa chọn "Giá liên hệ" (vẫn giữ khi URL cũ đang chọn, vẫn tính tỉ lệ phủ giá).
0.5.16 - 2026-10-15
- Nhóm lọc có hơn 10 lựa chọn có ô tìm (gõ không dấu vẫn ra, đang gõ thì hiện cả mục sau "Xem thêm"; giữ chữ đã gõ khi nhóm lọc được vẽ lại).
sort: "alpha"(A-Z tiếng Việt quaCollatorvi_VN) cho Loại đá và Hình tượng.- Bỏ nhóm lọc Xuất xứ khỏi mọi bộ
type_facets(giữ định nghĩa để URL cũ cóxuat-xuvẫn lọc được).
0.5.15 - 2026-10-15
- Bộ lọc Loại đá, Chế tác, Hình tượng hiện danh sách phẳng (
uilist) thay cây nhóm;Query_Engine::term_options()bỏ các term nhóm thuầng-*khỏi danh sách phẳng (trừ khi đang chọn qua URL). Xuất xứ giữ dạng cây.
0.5.14 - 2026-10-14 (lô LP5)
wp iga page-fixesbước 9 (Lp5_Hero::enable_load_more): bật loadMore cho các khốiiga/product-grid, giữ cột và hàng; chạy lại không đổi gì.
0.5.13 - 2026-10-14 (lô LH1)
wp iga page-fixesbước 10 (Lh1_Map): tranglien-hethay khối HTML chứa iframe Google Maps (kèm khối đệm 15px ngay sau) bằng khốiiga/store-mapcủa theme (toạ độ, tên, địa chỉ, place_id của hồ sơ Google "Infinity Gems An Thịnh"). Chỉ ghi khi đúng một khung Google Maps và chưa có khối bản đồ; chạy lại không đổi gì. Sao lưu ngoài webroot, kiểm băm, hoàn tác bằng--rollback.
0.5.12 - 2026-10-14 (lô F2)
- Bỏ nhóm lọc
ton-kho(Tình trạng):data/facets.json,Query_Engine(kindstock),Index_Builder(không còn ghi dòngton-kho).Archive::redirect_legacy_params()(template_redirect) 301 URL cóton-khovề URL không có tham số đó;Requestbỏ qua tham số. Index_Builder::PRIORITY_AVAILABLE/PRIORITY_SOLD:stock_prioritychỉ còn 1 (còn bán, gồm onbackorder) và 3 (outofstock);Indexer::reconcile()sửa lệch theo quy tắc mới.Schema::DB_VERSION2: bước nâng cấp xoá dòng indexton-kho, đổistock_priority2 và 4 thành 1, tăng phiên bản cache bộ lọc.- Lớp mới
Filter\Stock_Order: biến truy vấniga_sold_last;posts_clausesthêm LEFT JOIN bảngiga_product_sort(khoá chính product_id; chưa có index thì dùng meta_stock_status) và chèn biểu thức đã-bán vào đầu ORDER BY (phân trang đúng). Đo: JOIN postmeta chậm gấp 10-40 lần (postmeta không có chỉ mục post_id + meta_key), JOIN bảng sắp xếp thì không; tự bật cho truy vấn chính của sản phẩm (tìm kiếm, thẻ, thuộc tính, danh mục, cửa hàng);posts_pre_queryxếp lại kết quả tìm kiếm của engine tandoanh-code. - Shortcode lưới sản phẩm cũ (
Compat\FlatsomeShortcodes::sc_products) bậtiga_sold_last.
0.5.11 - 2026-10-14 (lô LP5)
wp iga page-fixesbước 8 (Lp5_Hero::strip_dup_heading): bỏ heading đầu nội dung trùng H1 của hero và khối spacer ngay sau; chạy lại không đổi gì.
0.5.9 - 2026-10-14 (lô LP5)
wp iga page-fixes: bước 6 thêm điểm giữ ảnh dọc theo khoá ảnh (AI_FY) và đổi ảnh khi ảnh hoặc điểm giữ đổi; bước 7 cập nhậtimageIdcủa 6 thẻ stone ở trang chủ theo ảnh AI mới nhất.
0.5.8 - 2026-10-14 (lô LP5)
wp iga page-fixesbước 7 (Lp5_Hero): đặt khốiiga/collection-gridkiểustone"Bộ sưu tập theo loại đá" vào chỗ khối cũ "Chọn theo loại tác phẩm" của trang chủ và gỡ khối cũ (nếu khối stone đã nằm chỗ khác thì dời về); không còn khối cũ thì chèn trước lưới "Top sản phẩm nổi bật"; bỏ qua nếu đã đúng chỗ hoặc thiếu ảnh AI. Sao lưu và hoàn tác như các bước cũ.
0.5.4 - 2026-10-14 (lô P3D)
- Mới
Portfolio\Portfolio: đăng ký lại kiểu bàifeatured_item, danh mụcfeatured_item_category, thẻfeatured_item_tagvà luật địa chỉ của Flatsome Portfolio (/bo-suu-tap/<slug danh mục>/,/bo-suu-tap/<slug danh mục nối dấu phẩy>/<slug mẫu>/,/featured_item/). Chỉ chạy khi chưa có kiểu bài này; phần đầu địa chỉ đổi được bằng filteriga_core_portfolio_base. Không ghi DB. Sau khi chép plugin lên một site phải chạywp rewrite flush(người dùng www-data) một lần. Forms\Ask_Price: khoá hỏi giábst-<ID>cho mẫu trang sức 3D (bàifeatured_itemđã đăng);subject()vàmessage()nhận thêm từ gọi đối tượng (mặc định "sản phẩm", mẫu 3D là "mẫu trang sức 3D"). Sản phẩm Woo không đổi.- Test:
tests/phpunit/Portfolio/PortfolioTest.php.
0.5.3 - 2026-10-14 (lô Q2)
Editor\Searchgiữtype=post, hiển thị ngày/chuyên mục và chỉ cảnh báo khi bài chưa có ảnh đại diện (bỏ cảnh báo 1200 px).wp iga page-fixes: việc 1c chỉnh khốiiga/news-feedcủa /kien-thuc/ (showBreadcrumb, showHeading, showFeatured, showChips = false; excludeCategories = chuyên mục slugkhuyen-mai) vàexcludeCategoriescủa banner. Sao lưu/hoàn tác như các việc cũ.
0.5.2 - 2026-10-14 (lô Q2)
Editor\Search: kiểu mớitype=postcho ô chọn bài của khốiiga/news-banner(lọc không dấu trên tiêu đề các bài đã đăng, cache 5 phút; trả kèm ngày, chuyên mục, ảnh nhỏ và cảnh báo khi bài chưa có ảnh đại diện hoặc ảnh dưới 1200 px).wp iga page-fixes: thêm việc 1b, trangkien-thucđã có khốiiga/news-feedmà chưa có banner thì chèn khốiiga/news-banner(bài mới nhất có ảnh lớn, 5 bài, 7 giây) ngay đầu nội dung, giữ nguyên phần còn lại. Có sao lưu ngoài webroot, kiểm băm, hoàn tác như các việc cũ; chạy lại không đổi gì.
0.5.1 - 2026-10-13 (lô Q1)
assets/js/iga-filter.js(+.min.js): class trạng thái trên<html>khi mở ngăn kéo đổi thànhis-filter-open/is-sort-open(tên cũ trùng class của nút mở nên CSS nút áp lên<html>và làm vỡ trang từ 1100px trở xuống).- Lệnh WP-CLI mới
wp iga page-fixes [--dry-run|--apply --backup-dir=<dir>|--rollback=<dir>]: (1) trangkien-thucdựng lại bằng một khốiiga/news-feed(chỉ ghi khi còn dấu hiệu bản cũ: bannerlinear-gradienthoặciga/news-teaser, chưa cóiga/news-feed); (2) khốiiga/product-gridcóheadingtrùng chữ tiêu đề trang thì bỏheading(H1 và H2 không còn giống nhau). Sao lưu JSON +ROLLBACK.sqlngoài webroot, kiểm băm từng file, kiểm slug/tiêu đề/trạng thái/meta không đổi sau khi ghi, hoàn tác bằng--rollback. Dùng lại được khi go-live.
Chưa phát hành
Sửa (lô L8, bảo mật và SEO)
Ip::client: qua Cloudflare chỉ tinCF-Connecting-IP(trước đây còn đọcX-Forwarded-For/X-Real-IPkhách tự gửi xuyên Cloudflare nên đổi IP né được giới hạn tần suất); qua proxy nội bộ lấy hop phải nhất không tin cậy củaX-Forwarded-For. ThêmIp::bucket(): IPv6 gộp theo /64 trongRate_Limiter(cũng áp choForms\Throttle).Filter\Seo::print_canonical: URL lọc/sắp xếp vừa noindex,follow vừa có canonical về URL sạch (Rank Math bỏ thẻ canonical trên trang noindex nên filter canonical cũ không có tác dụng).Editor\Search: routeiga/v1/editor-searchkhông trả sản phẩm chưa công khai cho người chỉ cóedit_posts(kiểmread_post).- Test:
IpTest(CF bỏ qua XFF/X-Real-IP, hop phải nhất, IPv6 /64),RateLimiterTest(cùng /64 chung bộ đếm).
0.5.0 - 2026-10-13
Lô LP3: trang landing sửa được kiểu hungphat (cột phải hiện đúng bảng thiết lập của từng phần).
Thêm
wp iga blocks-upgrade --dry-run | --apply --backup-dir=<dir> | --rollback=<dir>: nâng cấp trang block thô (core/group, core/cover, core/heading, core/spacer dowp iga ux2blockssinh ra) thành khốiiga/*. Chỉ nhận ra khuôn đã biết, khuôn lạ để nguyên; trang chủ (page_on_front) không bao giờ bị đụng.- A. Cặp cover băng rôn (một cái
iga-hide-smcho máy tính, một cáiiga-show-smcho điện thoại) thành mộtiga/hero-slidermột slide (ảnh máy tính, ảnh điện thoại, điểm giữ ảnh, kiểu "Thấp"). Chữ điện thoại trùng chữ máy tính thì gộp; khác thì giữ làmmobileTitle. Băng rôn máy tính đứng một mình giữ nguyên (chuyển sẽ làm nó hiện thêm trên điện thoại). - B. Tiêu đề h2 (kèm khoảng cách) đứng trước
iga/product-gridchưa có tiêu đề thành thuộc tínhheadingcủa lưới (kiểu "Gọn"); tiêu đề có thẻ lồng, h3 trở đi hoặc lớp lạ không gộp. - C. Nhóm
iga-sec/iga-coltrơn mà sau B chỉ còn khốiiga/*thì bỏ lớp bọc. - Chỉ ghi trang đạt mọi phép kiểm: chữ khớp 100% (bộ trích chữ của
Ux\Text), tập liên kết, ID và URL ảnh, thiết lập lưới sản phẩm, số H1 không đổi, tên khối đã đăng ký, chuỗi khối đọc lại ổn định. Sau ghi kiểm slug, tiêu đề, trạng thái, meta (gồm Rank Math, template) không đổi; lỗi thì tự khôi phục trang đó. - Sao lưu NGOÀI webroot trước khi ghi:
pages/<ID>.json(nội dung và toàn bộ meta, có băm),ROLLBACK.sql,posts-rows.sql.gz(mysqldumpREPLACE INTOđúng các hàng bài viết sẽ ghi, đọc lại kiểm),manifest.json,report.json. Mật khẩu DB cho mysqldump đi qua file tuỳ chọn tạm chmod 600, xoá ngay. Bản cũ còn trong revision. IGA\Core\Upgrade\Transformer(thuần PHP trên mảng khối),IGA\Core\Upgrade\Checker,IGA\Core\CLI\Blocks_Upgrade_Command. PHPUnittests/phpunit/Upgrade.
- A. Cặp cover băng rôn (một cái
Ux\Text: khoá thuộc tínhmobileTitletính là chữ hiển thị.
Đổi
Ux\Runner::meta_hashkhông tínhrank_math_og_content_image(bộ nhớ đệm ảnh OG Rank Math tự tính lại khi trang được xem, làm lệch băm meta khi hoàn tác).
0.4.1 - 2026-10-13
Lô L6: form công khai (liên hệ, hỏi giá, thanh toán). Không ghi gì vào DB, không cần chạy lệnh dữ liệu khi lên prod.
Thêm
IGA\Core\Forms\Phone: kiểm tra số điện thoại Việt Nam đúng (di động 03x 05x 07x 08x 09x theo dải đầu số đang cấp, số bàn 02x 11 số, dạng +84, 84, 0084,+84 (0) ..., chấp nhận khoảng trắng, chấm, gạch ngang, ngoặc). Thay đoạn regex hỏng/.../gcủa child theme Flatsome cũ (cờ g không có trong PCRE nên hàm luôn trả false). Gắn vàowpcf7_validate_telvàwpcf7_validate_tel*với câu lỗi rõ ví dụ.IGA\Core\Forms\Turnstile: Cloudflare Turnstile cho CF7 qua tích hợp sẵn của CF7 6.x. Khoá lấy từ HẰNG SỐIGA_TURNSTILE_SITEKEYvàIGA_TURNSTILE_SECRETtrong wp-config.php (filterwpcf7_turnstile_sitekey,wpcf7_turnstile_secret), không lưu khoá thật vào DB. Có khoá thì form bỏ khối quiz "10 x 5 = ?" và thêm[turnstile theme:dark size:flexible]trước nút gửi (viết lại mẫu form lúc chạy, không sửa form trong DB); chưa có khoá thì giữ quiz như cũ.IGA\Core\Forms\Throttle: giới hạn tần suất theo IP và theo nhóm (liên hệ 5 lần/10 phút, đặt hàng 12 lần/10 phút, đăng nhập 10 lần/10 phút; lọc quaiga_core_throttle_limits), dùng lạiFilter\Rate_LimitervàFilter\Ip(chỉ tin header Cloudflare khi kết nối đến từ dải Cloudflare/nội bộ). Bộ đếm: object cache bền vững nếu có (Redis), không thì transient có hạn. Form liên hệ đếm sau khi qua kiểm tra trường và trước bước gọi Cloudflare; thanh toán chỉ đếm lần đặt hợp lệ (không chặn khách gõ sai).IGA\Core\Forms\Ask_Price:/lien-he/?hoi-gia=<mã sp>điền sẵn chủ đềHỏi giá sản phẩm <tên> (<mã>)và nội dung... <link>cho form CF7 (tên trường mặc địnhyour-subject,your-message; đổi quaiga_core_ask_fields) kèm dòng "Bạn đang hỏi giá". Tham số GET chỉ là khoá tra cứu (chữ, số, . _ -, tối đa 64 ký tự); chữ điền vào lấy từ DB nên không có đường XSS. Trang có tham số không vào cache trang.IGA\Core\Forms\Comment_Guard: bình luận gửi thẳng tới wp-comments-post.php giới hạn 3 lần/10 phút/IP (trả 429).IGA\Core\Forms\Woo_Guard: giới hạn đặt hàng và đăng nhập Woo. Không dùng captcha ở thanh toán (mỗi lần captcha lỗi là mất một đơn).- CF7 chỉ nạp JS (và api.js của Turnstile) ở trang có form (
wpcf7_load_js, filteriga_core_cf7_neededcho vị trí khác). - Ô điện thoại của form nới
maxlength11 lên 20 (số có khoảng trắng hoặc +84), giữminlength. - Test PHPUnit
tests/phpunit/Forms(số điện thoại 47 ca, giới hạn tần suất, viết lại form, hỏi giá).
0.4.0 - 2026-10-13
Lô LP v2: ô tìm trực tiếp cho trình soạn thảo block.
Thêm
IGA\Core\Editor\Search: RESTGET /iga/v1/editor-search?type=product|product_cat|product_tag|category|term[&tax=pa_*]&q=..|ids=..|slugs=..&limit<=20, quyềnedit_posts. Sản phẩm dùng engine tìm tiếng Việt không dấu của tandoanh-code (chỉ mục, cache) khi có, không thì truy vấn tên và SKU không phân biệt dấu; trả ảnh nhỏ, tên, mã, giá hoặc "Giá liên hệ", tồn kho. Term lọc tại chỗ không dấu (cache 5 phút). Chữ trả về không dùng gạch dài. Kiểm bằng PHPUnittests/phpunit/Editor.
Chưa phát hành
Sửa (lô L8, bảo mật và SEO)
Ip::client: qua Cloudflare chỉ tinCF-Connecting-IP(trước đây còn đọcX-Forwarded-For/X-Real-IPkhách tự gửi xuyên Cloudflare nên đổi IP né được giới hạn tần suất); qua proxy nội bộ lấy hop phải nhất không tin cậy củaX-Forwarded-For. ThêmIp::bucket(): IPv6 gộp theo /64 trongRate_Limiter.Filter\Seo::print_canonical: URL lọc/sắp xếp vừa noindex,follow vừa có canonical về URL sạch (Rank Math bỏ thẻ canonical trên trang noindex nên filter canonical cũ không có tác dụng).Editor\Search: routeiga/v1/editor-searchkhông trả sản phẩm chưa công khai cho người chỉ cóedit_posts(kiểmread_post).- Test:
IpTest(CF bỏ qua XFF/X-Real-IP, hop phải nhất, IPv6 /64),RateLimiterTest(cùng /64 chung bộ đếm).
Đổi
- JS bộ lọc: thêm
assets/js/iga-filter.min.js(esbuild; 22,2 KB xuống còn khoảng 11 KB), không đổi hành vi.Assets::enqueuenạp bản rút gọn khi có file và không bậtSCRIPT_DEBUG; tên file trong uploads mang mtime nên cache-bust tự động.
Thêm
IGA\Core\Schema\Product_Schema(lô L3): bổ sung schema Product cho Rank Math, thay đoạn hard-code của child theme Flatsome cũ. MerchantReturnPolicy (đổi trả 3 ngày, applicableCountry VN) và OfferShippingDetails gắn vào mọi Offer; sản phẩm giá 0 hoặc trống không xuất Offer; thêm VideoObject cho sản phẩm có video YouTube,Product.videotrỏ tới nó. Filteriga/schema/return_policy,iga/schema/shipping.
0.2.1 - 2026-10-13
Lô L2 (giao diện danh mục) cần vài chỗ nhỏ trong module bộ lọc.
Thêm
- Filter
iga/filter/mobile_breakpoint(mặc định 959): điểm chuyển sang drawer; renderer ghidata-iga-bpvào cột lọc, JS đọc thay cho số cố định. - Filter
iga/filter/grid_html: theme đổi trạng thái rỗng và ưu tiên tải ảnh thẻ đầu (LCP) trên cả đường tải trang lẫn AJAX. - Filter
iga/filter/card_version: dấu phiên bản markup thẻ đưa vào khoá cache thẻ, đổi theme/thẻ thì thẻ cũ không còn được dùng. - JS: hỗ trợ nhiều vùng chip
[data-iga-chips](cột lọc và trên lưới) và khung lỗi do theme cấp ([data-iga-error],[data-iga-error-msg],[data-iga-retry]), hiện ngay trên vùng kết quả kể cả khi drawer đóng. - Chip đang chọn có tiền tố tên nhóm ("Loại đá: Sapphire").
Sửa
- Endpoint nhẹ không nạp Rank Math nên URL sản phẩm và danh mục trong phản hồi AJAX là URL gốc của WooCommerce (
/sản phẩm/slug/,/danh-muc-san-pham/cha/con/), khác URL trên trang và phải qua 301. Endpoint nay dựng lại cùng URL/slug/theo cài đặt của Rank Math (chỉ đọc optionrank-math-options-general); JS đổi phần gốc URL phản hồi (pushState, liên kết phân trang) vềdata-iga-basecủa trang. - Số đếm trong cột lọc và số lựa chọn đang tick không còn dấu ngoặc (theme tự định kiểu).
0.3.0 - 2026-10-13
Lô LP: chuyển UX Builder sang block và lớp tương thích Flatsome.
Thêm
wp iga ux2blocks --dry-run|--apply [--ids=..] [--backup-dir=..] [--out-dir=..] [--no-home] [--home-file=..]và--rollback=<thư mục> [--force]. Phân tích shortcode Flatsome (lồng nhiều cấp, thuộc tính nháy kép/đơn/không nháy,]trong giá trị, NBSP giữa thuộc tính, shortcode không đóng, thẻ đóng thừa) và chuyển sang khối core (heading, paragraph, list, quote, image, gallery, columns/column, group, cover, buttons, details, spacer, separator, embed YouTube, html, shortcode) và khốiiga/*(ux_products thànhiga/product-gridcùng nguồn, ux_slider thànhiga/hero-sliderkiểu banner, blog_posts thànhiga/news-teaser).- Giữ nguyên văn chữ: so chữ trước/sau từng trang, chỉ ghi khi khớp 100% (không tính khoảng trắng) và khối hợp lệ.
[block id=N]thành khối dùng lạiwp_block(meta_iga_ux_block) để sửa một chỗ đổi mọi trang. Trang chủ (page_on_front) được thay bằngthemes/iga/data/pages/home.blocks.html. - An toàn: sao lưu post_content + toàn bộ meta từng trang ra thư mục NGOÀI webroot và kiểm băm trước khi ghi, ghi trực tiếp
post_content/post_modified(kèm revision của bản cũ; không đổi slug, tiêu đề, template, meta Rank Math), kiểm lại sau ghi và tự khôi phục trang lỗi,ROLLBACK.sql+--rollbackkiểm băm sau khôi phục. IGA\Core\Compat\FlatsomeShortcodes: render tối thiểu section/row/col/gap/title/button/ux_image/ux_banner/ux_slider/ux_products/ux_gallery/block/blog_posts... chỉ khi shortcode chưa tồn tại (Flatsome không chạy), để không bao giờ hiện shortcode thô; filteriga_core_flatsome_compat_tags.- Action
iga_core_ux2blocks_page_writtensau mỗi trang được ghi (để xoá cache).
0.2.0 - 2026-10-13
Lô F1: ghi dữ liệu lọc và module bộ lọc AJAX.
Thêm
wp iga extract --apply [--batch=200] [--only=<nhóm>] --backup-dir=<thư mục>: ghi taxonomypa_loai-san-pham,pa_loai-da,pa_nhom-da,pa_che-tac,pa_hinh-tuong,pa_menh,pa_xuat-xu,pa_chat-lieu(đăng ký attribute WooCommerce nếu chưa có) và meta số đo_iga_*. Idempotent, theo lô trong giao dịch, không đổipost_modified, không đụng mô tả, chỉ ghi độ tin cậy high và medium, bỏ qua thuộc tính đang dùng làm biến thể, giữ term lạ sẵn có.- Sao lưu trước khi ghi (file nén, manifest có hash và số dòng, checksum bảng),
ROLLBACK.sqldựng trước khi ghi;wp iga extract --rollback=<thư mục>chạy trong một giao dịch rồi so checksum. - Bảng mệnh theo màu đá sửa được trong admin (option
iga_core_menh_overrides, D-12) và được bộ trích xuất đọc. - Module bộ lọc
IGA\Core\Filter(fork từ hungphat product-filter v6.12.1): bảng{prefix}iga_filter_indexvà{prefix}iga_product_sort, indexer rebuild theo lô không TRUNCATE, reindex khi lưu, đổi tồn kho hoặc giá (kể cả ghi meta trực tiếp), reconcile theo giờ, cờ đang rebuild kèm DONOTCACHEPAGE. Query_Enginedùng chung cho tải trang qua URL (thay truy vấn chính) và AJAX; AND giữa nhóm, OR trong nhóm, số đếm tính trừ nhóm hiện tại nên chọn một giá trị không ẩn giá trị khác cùng nhóm.- Nhóm lọc: các
pa_*ở trên, giá theo 7 mốc D-09 và nhóm Giá liên hệ (D-02, luôn xếp cuối khi sắp theo giá), khoảng số đog-*(chiều cao, trọng lượng, carat, size hạt), tồn kho, Có video; cấu hình theo loại sản phẩm trongdata/facets.json(D-10). - Endpoint nhẹ
runtime/iga-filter.php(chép ra webroot) + mu-pluginruntime/iga-fast-filter.php: giới hạn 60 yêu cầu mỗi phút mỗi IP (429), cache phản hồi Redis có tiền tố site và phiên bản, không cần nonce với khách. assets/js/iga-filter.js(không jQuery): pushState, popstate, phân trang AJAX cập nhật URL, drawer có bẫy focus, nút Xem N kết quả; sắp xếp là nút.- Canonical về URL sạch và
noindex,followcho URL lọc (Rank Math và wp_robots). - Trang admin iga-core > Bộ lọc: tình trạng index, nút dựng lại, phủ dữ liệu, giá trị chưa map, danh sách cần sửa tay (D-14), bảng mệnh, link YouTube hỏng, cài đặt.
IGA\Core\Video\ProductVideo::get()vàiga_product_video(): video YouTube từ meta Flatsomewc_productdata_options, không phụ thuộc theme; filteriga/product_video.- Template tag cho theme:
iga_filter_toolbar(),iga_filter_sidebar(),iga_filter_results(),iga_filter_pagination(); filteriga/filter/card_htmlđể theme thay thẻ sản phẩm. - Lệnh
wp iga filter rebuild|reindex|reconcile|status|query.
Ghi chú
- Tên meta số đo:
_iga_cao_cm,_iga_trong_luong_g,_iga_carat,_iga_size_hat_ly... - Bảng index được tạo khi kích hoạt plugin và chỉ bị xoá khi gỡ plugin (uninstall.php); vô hiệu hoá không xoá dữ liệu.
0.1.0 - 2026-10-13
- Khung plugin, bộ trích xuất thuộc tính (
wp iga extract --dry-run), bảng ánh xạ loại đá, mệnh, hình tượng, xuất xứ, chất liệu.