=== smartest.email ===
Contributors: logicossoftware
Tags: newsletter, email marketing, signup form, double opt-in
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.2.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connect WordPress to smartest.email and publish accessible newsletter signup forms with explicit consent and email confirmation.

== Description ==

smartest.email brings your workspace's signup forms to WordPress. Connect securely, choose a form and publish it using the native block editor or a shortcode. Campaigns, contacts, consent records and email delivery stay in smartest.email.

The plugin supports individual WordPress installations. WordPress multisite is not supported yet. A smartest.email account, HTTPS and at least one active double opt-in form with required consent and a privacy policy URL are required. No paid checkout or plan entitlement is introduced by this plugin.

Features:

* Secure connection using OAuth authorization codes, S256 PKCE and rotating refresh tokens; no shared client secret or API key to paste.
* Native "smartest.email signup form" block and [smartest_email_form id="FORM_UUID"] shortcode.
* Searchable form selection and live, non-submitting previews in the block editor and plugin settings.
* Responsive stacked/two-column fields, standard/full width, custom button labels and full-width buttons, with matching shortcode options.
* Native block color, typography and spacing controls where supported by your theme.
* Searchable form cards and one-click shortcode copying, with a manual-copy fallback.
* Current form fields, consent copy and privacy policy link from smartest.email.
* Accessible labels, browser validation, readable status messages and styles that work with your theme.
* Email confirmation before a new contact becomes subscribed. Existing unsubscribed or suppressed addresses are not reactivated.
* Idempotent retries after network failures. An uncertain submission keeps its original payload and identifiers in page memory until resolved or the page is closed.
* Local nonces, signed short-lived form contexts, honeypot and request limits. These complement the service's subscription limits; they are not a CAPTCHA.
* Connection status, refreshable form list and local disconnection.
* Translatable WordPress controls and messages.

== External service ==

This plugin connects to the smartest.email service at https://smartest.email and https://api.smartest.email.

When a site administrator connects, the browser opens smartest.email for approval. WordPress then exchanges the returned code for access and refresh tokens. The plugin sends authenticated requests to retrieve the connected workspace's name and eligible form definitions. It sends token refresh and revocation requests when needed.

When a visitor explicitly submits a form, the plugin sends the declared form fields (including the email address), the current consent text, a consent timestamp, the selected form ID, a random installation ID and a random submission ID to smartest.email. smartest.email records consent, enforces suppression and sends any required confirmation email. The plugin does not send the visitor's IP address to smartest.email.

OAuth credentials are encrypted with WordPress salts and stored in a non-autoloaded option. Changing those salts requires reconnecting. Cached form definitions expire after five minutes. Local anti-abuse counters store salted hashes of visitor IP addresses for up to six minutes; raw IP addresses are not stored by this plugin. Subscriber fields are not persisted in WordPress, plugin logs, localStorage or sessionStorage. Other site infrastructure may keep its own request logs.

Disconnect before deleting the plugin to revoke the service grant. If revocation cannot be confirmed, the local credentials are still removed and a notice explains how to revoke the connection in smartest.email. Uninstall removes local plugin options and database-backed transients; cached transient entries in an external object cache expire normally. Uninstall does not delete contacts, consent records or forms in smartest.email.

Service and support: https://smartest.email
Setup guide: https://smartest.email/docs/integrations/wordpress
Privacy policy: https://smartest.email/privacy
Terms: https://smartest.email/terms

== Installation ==

1. Upload the smartest-email ZIP through Plugins → Add New → Upload Plugin, or copy the smartest-email directory to wp-content/plugins/.
2. Activate the plugin on an individual WordPress installation.
3. Open Settings → smartest.email and select Connect to smartest.email.
4. Sign in to smartest.email, check the displayed WordPress callback domain and approve the workspace connection.
5. Create an active double opt-in signup form in smartest.email with a required consent checkbox and a privacy policy URL. Select Refresh forms in WordPress if necessary.
6. Add the smartest.email signup form block to a page and choose the form. Alternatively, copy the shortcode from the settings page.
7. Review the published page and your privacy notice before inviting visitors to subscribe.

Sodium or OpenSSL is required for encrypted credential storage. Production connections require valid HTTPS certificates. JavaScript must be enabled in visitors' browsers to submit a form.

== Frequently Asked Questions ==

= Does this plugin send campaigns from WordPress? =

No. Campaign creation and delivery stay in smartest.email. This plugin connects your website and collects newsletter signup consent.

= Does installing it subscribe existing WordPress users? =

No. There is no user import or automatic subscription. A visitor must submit the form and confirm when required. Existing and suppressed addresses receive the same generic response.

= Can I edit the form in WordPress? =

Choose the form in WordPress and manage its fields and consent copy in smartest.email. Block appearance controls affect only that placement; they cannot remove required fields, consent, the privacy link or email confirmation. Cached definitions expire after five minutes. If a form changes while a visitor is completing it, they must reload and review the updated consent before submitting.

= Which shortcode appearance options are supported? =

[smartest_email_form id="FORM_UUID" layout="two-column" width="full" button_width="full" button_label="Join our newsletter"]

layout accepts stacked (default) or two-column. width accepts standard (default) or full. button_width accepts auto (default) or full. button_label is plain text, up to 80 Unicode characters; leaving it empty uses the translated Subscribe label. Two-column layouts stack on small screens. Native WordPress color, typography and spacing controls belong to blocks; use a styled Group block around a shortcode when needed. Existing formId-only blocks and id-only shortcodes retain their defaults.

= Can previews send a subscription? =

No. Editor and settings previews show the current form with disabled fields and no submission context or live form handler. Use a published page for an intentional signup test. Preview routes require an authenticated user who can edit posts and a WordPress REST nonce.

= What happens if the connection fails while submitting? =

The visitor can safely retry in the same page. The plugin retains the original submission identifiers, values and consent time in memory so the service can avoid duplicate confirmation emails. Do not reload the page until an uncertain request has been resolved.

= Why do I need to reconnect? =

The authorization may have been revoked, the authorizing user's permissions may have changed, WordPress salts may have changed, or a refresh response may have been lost. The plugin does not replay a refresh token after an uncertain rotation.

= Does this work with page caching? =

Yes. Submission nonces and signed contexts are fetched immediately before posting, with no-store response headers. Exclude /wp-json/smartest-email/v1/ from any cache rules that override those headers. Purge page caches when changing form fields or consent copy.

= Does it support WooCommerce or other form plugins? =

Only the native block and shortcode are included. Purchase-triggered campaigns, checkout opt-in and third-party form adapters are not implemented.

= Can I use a reverse proxy? =

Yes. Configure WordPress's HTTPS and home URL correctly. The plugin uses REMOTE_ADDR for local anti-abuse limits and does not trust arbitrary forwarding headers. Your trusted proxy configuration should supply the correct client IP.

== Developer testing ==

For isolated local testing only, set WP_ENVIRONMENT_TYPE to local or development and define SMARTEST_EMAIL_DEV_API_ORIGIN and SMARTEST_EMAIL_DEV_APP_ORIGIN in wp-config.php. Each override must use a literal loopback host (localhost, 127.0.0.1 or ::1) with no credentials, path, query or fragment. These overrides are ignored in production. The backend must independently allow loopback callbacks in development/test. No endpoint can be entered through the WordPress dashboard.

Run the standalone contract harness with PHP 8.1+:

php tests/run.php

This harness uses fake WordPress functions and a fake transport. A separate isolated WordPress activation and browser check is required for a release.

== Changelog ==

= 0.2.0 =

* Add searchable form selection, refresh/retry states and a live read-only block preview.
* Add responsive layout, width and button options with shortcode parity and native block styling.
* Add searchable settings cards, read-only previews and accessible shortcode copying.
* Preserve centrally managed consent and required fields; translate the new interface in all 19 supported languages.

= 0.1.0 =

* Initial single-site connection, block, shortcode and double opt-in subscription implementation.
