=== WooCommerce Review Importer ===
Contributors: makitsolutions
Tags: woocommerce, reviews, csv, xlsx, importer
Requires at least: 6.4
Tested up to: 6.8
Requires PHP: 7.4
Stable tag: 1.0.9
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Preview, validate, and safely import WooCommerce product reviews from CSV or XLSX files.

== Description ==

WooCommerce Review Importer adds WooCommerce > Review Importer. It supports column mapping, a 20-row preview, dry runs, URL-to-product matching, duplicate policies, resumable AJAX batches, history, and downloadable row-level reports.

CSV support uses native PHP. XLSX support uses a small read-only parser built on PHP's ZipArchive and SimpleXML extensions. It reads values from the first worksheet and has no external service or third-party library dependency. It does not execute formulas, macros, or embedded content.

Product matching never fetches a supplied URL. Local URLs can resolve by WordPress post ID or product slug. Variation URLs attach reviews to the parent product. External hosts are rejected unless explicitly allowed; when allowed, matching is still local and uses only an ID or slug parsed from the URL.

== Installation ==

1. Copy the plugin directory to `wp-content/plugins/woocommerce-review-importer`, or upload its ZIP in Plugins > Add New.
2. Activate WooCommerce.
3. Activate WooCommerce Review Importer. Activation creates and verifies the `wp_wcri_jobs` and `wp_wcri_rows` tables using the site's actual WordPress table prefix. Activation stops with the database's reason if either table cannot be initialized.
4. Open WooCommerce > Review Importer.

For XLSX files, enable the PHP `zip` and `simplexml` extensions. CSV files do not require them.

== Usage ==

1. Prepare a CSV or XLSX file with a header row. See `examples/reviews-example.csv`.
2. Select the file and choose duplicate, status, batch, external-URL, and dry-run options.
3. Select Read headers and preview. This request only reads the temporary PHP upload and returns the detected headers and first 20 rows; it does not create a job or save spreadsheet rows.
4. Review the suggested column mappings, then select Validate preview. The browser resends the selected file and the plugin creates the recoverable job only after the mapping is accepted. Invalid rows are displayed and will become row-level errors.
5. Select Publish reviews and confirm. Use Pause, Resume, or Cancel as needed. “Published (approved)” makes imported reviews publicly visible; pending and spam reviews are not publicly displayed.
6. Download the CSV report from the active job or Import history.

Required mapped fields are Product URL, Review content, Reviewer name, and Rating. Optional fields are reviewer email, title, date/time, status, and verified purchase. Status values are `approved`, `pending`, or `spam`; verified values accept yes/no, true/false, y/n, or 1/0.

Review dates accept day-first `DD/MM/YYYY` values such as `17/12/2025`, ISO `YYYY-MM-DD`, and either format with an optional 24-hour time. Day-first values are parsed explicitly and are never interpreted as month-first dates.

== Security and storage ==

Only users with `manage_woocommerce` can use AJAX actions or download nonce-protected reports. The initial preview reads PHP's request-scoped temporary upload and stores nothing. After mapping, the browser resends the file; parsed rows are committed to the recoverable import tables, while the source file itself is not retained. Job and row history remains so reports and audit counts are retained.

The default maximum file size is 10 MB and the default maximum row count is 100,000. Filters can change both limits.

Each AJAX processing request can handle between 1 and 1,000 reviews. The default is 25 for broad hosting compatibility. A batch size of 1,000 is available for servers with sufficient PHP execution time and memory, and interrupted jobs remain resumable.

== Uninstall ==

Import history is preserved by default. To remove the custom tables, options, and stored source files during uninstall, define `WCRI_REMOVE_DATA_ON_UNINSTALL` as `true` in `wp-config.php` before deleting the plugin. Imported product reviews are never deleted by uninstall.

== Frequently Asked Questions ==

= Does the importer visit product URLs? =

No. URLs are parsed locally. There are no arbitrary server-side HTTP requests.

= How are duplicates found? =

A SHA-256 fingerprint combines the matched parent product, reviewer email (or name), normalized review content, rating, and supplied review date. The fingerprint and import job/row identifiers are saved as comment metadata.

= What happens after an interrupted request? =

Open Import history and select Continue. Finished rows are not repeated, and an unfinished claimed row is returned to pending when the job resumes.

== Changelog ==

= 1.0.9 =
* Polished the admin interface with a violet theme, workflow indicator, CSV template download, responsive forms, and a clearer history empty state.
* Added accessible progress labels, keyboard focus styles, loading indicators, and reduced-motion styling.
* Reset the validation button correctly when previewing another spreadsheet.

= 1.0.8 =
* Added strict support for day-first DD/MM/YYYY review dates and optional times.
* Added clearer date-format validation errors and rejection of impossible calendar dates.

= 1.0.7 =
* Redesigned the importer workflow with responsive step headings, a drag-and-drop file picker, grouped settings, clearer option descriptions, and improved mobile layout.

= 1.0.6 =
* Increased the configurable review-processing batch limit from 200 to 1,000.

= 1.0.5 =
* Create and verify every importer table during plugin activation.
* Replaced the MariaDB-reserved `row_number` database column with `source_row`.
* Added migration support for installations that already have the legacy column.

= 1.0.4 =
* Added verified, independent creation and repair of both importer database tables.
* Added a direct schema fallback and actionable database-permission errors when hosting blocks table creation.
* Removed partially created job records when row persistence fails.

= 1.0.3 =
* Added inline validation feedback with row-specific failure reasons next to the Validate preview button.
* Prevented job creation when a preview row is invalid and added detailed database failure reasons.

= 1.0.2 =
* Made the Publish reviews step visible immediately after reading headers and enabled it after mapping validation.
* Clarified that WooCommerce's approved review status means published.

= 1.0.1 =
* Changed the first request to show headers and preview without creating a job or saving spreadsheet rows.
* Added an explicit detected-header list and automatic custom-table repair on plugin updates.

= 1.0.0 =
* Initial release.
