=== APSearch — Arabic & Persian Search ===
Contributors: faizahmaddae
Tags: arabic, persian, farsi, search, urdu
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Arabic and Persian searches return nothing when the spelling differs by one invisible character. This makes them match.

== Description ==

WordPress search fails on Arabic-script languages, and it fails silently. A visitor searches **کتابها** and gets nothing, because the post says **کتاب‌ها** with a zero-width non-joiner. Someone types **كتاب** with an Arabic Kaf while the content uses the Persian **ک**. A product title carries diacritics; the query does not. Every one of these is a lost search, a lost reader, and in a shop, a lost sale.

This plugin fixes it by keeping a normalized copy of your searchable text and matching queries against that copy.

**What it normalizes**

* Yeh family: ي, ى, ئ, ے, ې → ی
* Kaf family: ك, ڪ → ک
* Alef family: أ, إ, آ, ٱ → ا
* Heh family: ة, ۀ, ہ, ھ → ه
* Diacritics (harakat), Quranic marks and kashida/tatweel are ignored
* Arabic-Indic (٠-٩) and Extended Arabic-Indic (۰-۹) digits become 0-9
* Zero-width non-joiner (ZWNJ / نیم‌فاصله) and other invisible marks are ignored
* Punctuation and repeated whitespace are ignored

**Works with**

* The built-in search form and search results page
* Any theme or block that runs a WP_Query search
* WooCommerce product search (enable the `product` post type in settings)
* WP-CLI: `wp apsearch reindex`, `wp apsearch status`, `wp apsearch normalize "متن"`

**Privacy**

The plugin sends nothing anywhere. It stores one normalized text field per post in your own database.

== Installation ==

1. Install and activate the plugin.
2. Go to **Settings → APSearch**.
3. Choose which post types to index and press **Build / rebuild index**.
4. Search your site and compare.

== Frequently Asked Questions ==

= Do I need to rebuild the index after adding a post? =

No. Posts are indexed automatically when saved. A full rebuild is only needed after you install the plugin or change the normalization rules.

= Does this slow down my site? =

Search adds one LEFT JOIN on a single meta row per post. Indexing happens on save, not on view.

= Does it work with a search plugin like Relevanssi or SearchWP? =

Those plugins replace WordPress search entirely rather than filtering it, so this plugin steps aside and your results come from them. If Relevanssi is active you will see a one-time notice in the admin saying so.

You then have two choices: deactivate the other plugin and search with this one, or keep it and feed it this plugin's normalization using the snippet in the next answer.

= How do I make Relevanssi understand Arabic and Persian spelling? =

Relevanssi stores search terms exactly as they are written, so `کتاب‌ها` (with ZWNJ) and `کتابها` stay different words to it, as do `كتاب` and `کتاب`, and `۱۴۰۳` and `1403`.

Add this to your theme's `functions.php` or a small site plugin:

`
add_filter(
	'relevanssi_remove_punctuation',
	function ( $string ) {
		if ( class_exists( 'APSearch_Normalizer' ) ) {
			$string = APSearch_Normalizer::normalize( $string );
		}
		return $string;
	},
	20
);
`

Relevanssi runs that filter inside its tokenizer, which it uses both when indexing your posts and when parsing what a visitor typed. Normalizing in one place therefore fixes both sides at once. Priority 20 makes it run after Relevanssi's own punctuation handling.

**Rebuild the Relevanssi index after adding this** (Relevanssi's own settings screen), or its stored terms will still be the unnormalized ones.

This is a documented starting point, not a supported integration — the snippet touches Relevanssi's filter, and Relevanssi's own settings still decide what gets indexed.

= Does it support Urdu, Pashto, Kurdish or Hebrew? =

Urdu, Pashto and Dari letter variants are covered. Hebrew needs no normalization of this kind and is unaffected.

== Screenshots ==

1. Settings screen with index status.
2. Normalization rules.
3. The normalization test tool.

== Changelog ==

= 0.1.0 =
* First release.
