=== OmniDirectory ===
Contributors: soulja, kerio
Tags: directory, staff directory, team directory, search, multilingual
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 4.3.27
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A multi-purpose directory plugin with bilingual Arabic/English search, multiple layouts, document uploads, and click-to-reveal privacy protection.

== Description ==

OmniDirectory registers a "Directory Members" custom post type and lets you build a searchable staff/member directory that adapts to almost any profession — doctors, lawyers, consultants, clergy, companies — just by relabeling three custom fields from Directory Settings.

**Core features:**

* Custom post type ("Directory Members") with a photo, three admin-configurable fields (e.g. Specialty/Title, Location/Office, Phone), Email, Bio, and an optional "Directory Category" taxonomy.
* Live AJAX search shortcode `[omnidirectory_search]`, restricted to matching Title and Directory Category (no false-positive matches from unrelated meta/content).
* Built-in Arabic + English search: an Arabic search term automatically matches Arabic listings and an English term matches English listings, with Arabic letter-variant normalization (e.g. "احمد" and "أحمد" match each other) baked in, and full RTL support throughout.
* Eight search-results layouts: Modern Grid Cards, Horizontal List Row, Avatar Badge Compact, Structured Table View, Masonry Pinterest Grid, Horizontal Directory List, Compact Table Matrix, and Interactive Hover Flip Cards — switchable from Directory Settings.
* Eight single-profile layouts: Modern Centered Card, Two-Column Sidebar, Hero Banner Top, Tabbed Profile View, Minimalist Clean, Split Screen Cover, Interactive Dashboard, and Floating Card Overlay.
* Attachments / Documents: attach PDF, Word, Excel, or plain-text files to a member's profile, with an optional custom label per file, shown as a labeled download card on their profile.
* Click-to-Reveal privacy option: optionally mask phone numbers and email addresses behind a "Click to show" button, to deter basic spam-harvesting bots.
* Category filter dropdown, a primary accent color picker, an "hide empty fields" display toggle, and a CSV Import/Export module for bulk-adding or backing up your directory.
* Polylang and WPML compatible: the post type, taxonomy, and translatable fields are registered for both, with a `wpml-config.xml` file included for WPML.

= Getting Started =

1. Activate the plugin.
2. Go to **Directory Members → Directory Settings** to relabel the custom fields for your use case (e.g. "Specialty / Title" for a medical practice, "Practice Area" for a law firm) and choose your preferred search/profile layouts.
3. Add members under **Directory Members → Add New**, or bulk-import them via **Directory Members → Import / Export**.
4. Place the `[omnidirectory_search]` shortcode on any page to show the live search box.

== Installation ==

= Automatic installation =

1. In your WordPress admin, go to **Plugins → Add New**.
2. Search for "OmniDirectory".
3. Click **Install Now**, then **Activate**.

= Manual installation =

1. Download the plugin zip file.
2. In your WordPress admin, go to **Plugins → Add New → Upload Plugin**.
3. Choose the zip file and click **Install Now**.
4. Activate the plugin through the **Plugins** menu.

= After activation =

1. Visit **Directory Members → Directory Settings** to configure field labels, layouts, and colors.
2. Add your directory members under **Directory Members → Add New**.
3. Add the `[omnidirectory_search]` shortcode to any page or post where you want the search box to appear.

== Frequently Asked Questions ==

= Can I use this for something other than a clergy or medical directory? =

Yes. The three custom fields (default labels: Specialty/Title, Location/Office, Phone Number) can be relabeled from Directory Settings to fit any profession — law firms, consultancies, companies, or any other member/staff directory.

= Does the search work in Arabic? =

Yes. The search automatically detects whether the typed term is Arabic or English (based on the characters typed, regardless of the site's active language) and matches accordingly, including common Arabic letter variations (e.g. different Alef forms, ta marbuta vs. ha).

= Is it compatible with Polylang or WPML? =

Yes. The custom post type and Directory Category taxonomy are registered as translatable for both plugins, and a `wpml-config.xml` file is included with the plugin to declare which custom fields WPML should treat as translatable.

= What file types can I attach to a member's profile? =

PDF, Word (.doc/.docx), Excel (.xls/.xlsx), and plain text (.txt). Every uploaded file's actual MIME type is validated against this list on the server, not just restricted in the browser's file picker.

= How do I bulk-add members instead of entering them one at a time? =

Go to **Directory Members → Import / Export** and upload a .csv file. Column headers are matched automatically against common naming variants (e.g. "Title" or "Full Name" both map to Name), so you don't need to match this plugin's exact export format exactly.

= Does click-to-reveal fully hide phone/email from all bots? =

It's a lightweight deterrent (similar to common "email cloaking" plugins), not a guarantee: the real value is kept out of the page's initial HTML and only inserted after a visitor clicks. It's designed to stop basic scrapers that scan static HTML for phone/email patterns, not a bot that fully executes JavaScript and specifically targets this markup.

== Screenshots ==

1. Live search results in the default Modern Grid Cards layout.
2. A member's profile page in the Tabbed Profile View layout.
3. Directory Settings: field labels, layout pickers, and color/display toggles.

== Changelog ==

= 4.3.27 =
* Fix: a fatal error on member profile pages when a companion plugin added markup with a `display` CSS style — a callback was declared `private` but WordPress's hook system calls it from outside the class.

= 4.3.26 =
* Fix: the Polylang custom-field-sync filter now removes only this plugin's own fields, instead of unconditionally emptying the whole list (which silently disabled that Polylang feature for every other plugin's fields too).

= 4.3.25 =
* Fix: 4 settings (search placeholder, post type label, items per page, primary color) now correctly autoload, removing 4 unnecessary individual database queries per page load.

= 4.3.24 =
* Security: companion-plugin hook output (Action Bar, Interactive Map, QR Code, Rich Text Editor) is now escaped with `wp_kses()` instead of echoed raw.
* Security: CSV import now rejects malformed upload data before it can trigger a PHP error.

= 4.3.23 =
* Added a "Recent Activity" log on the Import/Export page, recording settings resets and CSV exports/imports.

= 4.3.22 =
* Removed the unused 'wysiwyg' meta-field mechanism entirely (was inactive on Free, per WordPress.org Trialware guidelines) and replaced it with two generic extension filters for companion plugins.
* Security: reduced unescaped-output exceptions from 52 to 2, with every remaining case individually justified.

= 4.3.21 =
* Added `omnidirectory_search_result_rendered` action for companion-plugin search-impression tracking. No effect by itself.

= 4.3.20 =
* Added Schema.org (JSON-LD) structured data to single member profile pages for better search engine understanding.

= 4.3.19 =
* Added `omnidirectory_settings_page_after` action for companion plugins to add their own settings sections. No effect by itself.

= 4.3.18 =
* CSV import now clears the existing directory (to Trash, recoverable) before importing, preventing duplicate entries on re-import.

= 4.3.17 =
* Moved the companion-plugin Action Bar extension point from search cards to the single profile page.

= 4.3.16 =
* Added `omnidirectory_result_card_actions` extension point for companion plugins. No effect by itself.

= 4.3.15 =
* Fixed a raw `<style>` tag on the Directory Settings page to use proper WordPress asset enqueuing, per WordPress.org review feedback.

= 4.3.14 =
* Updated "Tested up to" version per WordPress.org's requirements.

= 4.3.13 =
* Addressed WordPress.org review feedback: added reviewer to Contributors list; fixed 2 more unescaped-output findings.

= 4.3.12 =
* Fixed a Plugin Check false-positive warning on Bio field output (no functional change; output was already sanitized).

= 4.3.11 =
* Fixed the Rich Text Editor's text being invisible in dark-mode browsers.

= 4.3.10 =
* Fixed the Rich Text Editor's toolbar failing to load in some environments by explicitly enqueuing its assets.

= 4.3.9 =
* Diagnostic build (superseded by 4.3.10).

= 4.3.8 =
* Simplified the Bio field's Rich Text Editor rendering; removed a redundant asset-loading call.

= 4.3.7 =
* Fixed the Rich Text Editor's toolbar reverting to defaults on page reload.

= 4.3.6 =
* Removed the unused default content editor from the Directory Member edit screen.

= 4.3.5 =
* Fixed a translated member profile 404 issue on multilingual (Polylang) sites.

= 4.3.4 =
* Adjusted the Rich Text Editor's internal ID format for better compatibility.

= 4.3.3 =
* Directory Member edit screens now always use the classic editor, for Rich Text Editor reliability. Filterable.

= 4.3.2 =
* Fixed the Rich Text Editor's toolbar not loading its full configuration under the Block Editor.

= 4.3.1 =
* Minor compatibility and stability fixes.

= 4.1.0 =
* Fixed several PHPCS code-standards findings in the CSV export/import handlers, with no behavior change.

= 4.0.0 =
* Replaced the Sample Data Generator with a full CSV Import/Export module, including automatic column matching and image fetching.

= 3.10.0 =
* Added 3 more optional custom fields (Field 3, 4, 5), each with a customizable label.

= 3.9.0 =
* Rebuilt the single-profile Language Switcher on buttons instead of links, for reliability.

= 3.8.1 =
* Resolved 9 PHPCS code-standards findings, with no behavior change to search or multilingual support.

= 3.8.0 =
* The Language Switcher now swaps profile content via AJAX in place, without a full page reload.

= 3.7.1 =
* Hardened the multilingual (Polylang/WPML) integration against partial or broken installs.

= 3.7.0 =
* Added an automatic Single Profile Language Switcher for Polylang/WPML sites.

= 3.6.0 =
* Explicit Polylang/WPML integration improvements for post type and category visibility.

= 3.5.1 =
* Fixed Arabic search results being excluded on language-mismatched pages.

= 3.5.0 =
* Fixed multilingual (Polylang/WPML) search to correctly stay scoped to the visitor's language.

= 3.4.3 =
* Resolved the final Plugin Check warning.

= 3.4.2 =
* Resolved 4 more Plugin Check warnings on a search query.

== Upgrade Notice ==

= 3.4.0 =
Recommended update: resolves all WordPress Plugin Check findings (heredoc usage, header fields, escaping, sanitization, and SQL preparation) with no feature changes.
