# 🔑 Factorize Portal

> One box, one button — sign in or sign up, nobody fills two forms.
>
> **Suite identity:** icon 🔑 · accent `#58c9b9` · part of the [Factorize suite](../README-FACTORIZE.md)

## What it does

Replaces the stacked login + register forms on the logged-out WooCommerce My Account page with a single email-first flow: enter your email, and the panel either reveals the password field (existing account) or flips into create-account mode and submits the real hidden register form. It also adds an optional phone-number field to WooCommerce registration, validates its format when provided, and saves it to the customer's `billing_phone` user meta. No-JS visitors still get the classic two-form page; WooCommerce nonces and server-side validation are untouched.

## Configuration

| key | default | effect |
| --- | --- | --- |
| `phone_field_enabled` | `true` | When true, the three registration phone hooks are active: the phone field renders on the register form, the format validation runs, and the number is saved to `billing_phone` on account creation. Set false to disable all three. |

Configuration is read through `empire_portal_config( $key )`. Values come from the `factorize-portal_options` option (an array merged over the defaults; a legacy `empire-account-portal_options` row is honored as a fallback), and the merged result then passes through the `factorize-portal_config` filter, so either an option row or a filter callback can override any key.

## Works with

- Requires WooCommerce for anything visible: the phone field hangs off `woocommerce_register_form` / `woocommerce_registration_errors` / `woocommerce_created_customer`, and the portal script only enqueues when `is_account_page()` exists and returns true. Without WooCommerce the plugin loads but does nothing (the enqueue callback guards with `function_exists( 'is_account_page' )`).
- The portal's CSS classes (`et-portal`, `et-portal__stage2`, etc.) are styled by the suite's companion theme stylesheet — the theme keeps all CSS. On another theme the flow still works but unstyled.
- Calls no functions from sibling Factorize plugins and none call into it; it degrades gracefully on its own.

## Hooks it registers

- `woocommerce_register_form` (action) — outputs the optional phone field on the registration form.
- `woocommerce_registration_errors` (filter) — rejects a provided phone number that does not look like one.
- `woocommerce_created_customer` (action) — saves the submitted phone to `billing_phone` user meta.
- `wp_ajax_et_check_user` / `wp_ajax_nopriv_et_check_user` (actions) — `empire_tools_check_user()`, the nonce-checked AJAX lookup that reports whether an account exists for an email/username.
- `wp_enqueue_scripts` (action) — enqueues `assets/js/account-portal.js` (handle `empire-tools-account-portal`, filemtime-versioned) and localizes `etPortal` (AJAX URL + nonce) on the logged-out account page only.

## Publishing

`readme.txt` (the WordPress.org listing copy) and `QUICKSTART.md` (the 5-minute setup guide) live alongside this file and are the publication material for the WordPress.org release.
