=== Porsino Forms ===
Contributors: porsino
Tags: form, survey, quiz, popup, woocommerce
Requires at least: 5.8
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Embed Porsino forms, surveys and quizzes in WordPress: block, shortcode, Elementor widget, floating button, auto popup and WooCommerce surveys.

== Description ==

[Porsino](https://porsino.com) is a Persian-first form, survey and quiz builder. This plugin puts the forms you build there on your WordPress site — no copy-pasted HTML, no external scripts on your pages.

**Ways to place a form**

* **“Porsino form” block** for the block editor, with a live preview of the form right in the editor.
* **`[porsino]` shortcode** for any editor, widget area or page builder.
* **Elementor widget** “Porsino form” (only when Elementor is active).
* **Classic editor button** “Add Porsino form” that opens a small dialog and inserts the shortcode.
* **Floating button** on the pages you choose (all pages, the home page, posts, pages or specific IDs, with exclusions), at a corner or as a vertical tab on the screen edge, optionally hidden on phones.
* **Auto popup** on the pages you choose: after a number of seconds, after the visitor scrolls part of the page, or on exit intent (with a timer fallback on touch screens) — every visit, once per browser session or once every few days. It is never shown to bots, never over another Porsino popup, never again after the visitor has answered it, and (optionally) never to logged-in editors.
* **WooCommerce thank-you page**: show a form (for example a satisfaction survey) on the order-received page, with the order number passed to it.

**Display modes**

* **Inside the page:** the form takes exactly the height of its content, so long, multi-page or conditional forms never get an inner scrollbar.
* **Button and popup:** a button opens the form in an accessible dialog (Esc, the close button or a click outside closes it; focus returns to where it was).
* **Quizzes** always open on their own Porsino page in a new tab — their timer and rules need it — so a quiz is shown as a button that links there, never inside a frame.

**Optional: connect your Porsino account**

Connecting is optional; everything above works without it. When you connect (Settings › Porsino › Connect account), you choose forms from a searchable list in the block editor, the Elementor widget and the classic-editor dialog; quizzes and unpublished forms are recognised automatically (editors see a note when a form is not published yet); and a “Porsino” dashboard widget shows your latest forms with their response counts. The connection key can only list your forms, is never shown in any page or script, and can be revoked here or in Porsino at any time.

**Passing data into forms (opt-in)**

A Porsino form can store values from its address in hidden fields. With these options WordPress adds them to the form’s address — nothing is sent unless you turn it on:

* `utm="1"` — the page’s `utm_source`, `utm_medium`, `utm_campaign`, `utm_term` and `utm_content` (added in the visitor’s browser, so cached pages stay correct);
* `page="1"` — `wp_page` (the page address without its query) and `wp_title`;
* `user="1"` — `wp_name` and `wp_email` of logged-in users only (the page is then marked as not cacheable);
* `params="key=value&key2=value2"` — fixed values (keys: lowercase letters, digits and `_`; values up to 200 characters);
* WooCommerce: `order_id`, and only if you turn them on, `order_total`, `customer_name` and `customer_email`.

In Porsino, add a **Hidden field** to the form, set its value source to **URL parameter** and its parameter name to the same name (for example `wp_page`).

**Analytics**

If the site uses Google Tag Manager or Google Analytics, every successful submit sends a `porsino_form_submit` event to the site’s own `dataLayer`/`gtag` (with the form address only, never the answers), and a `porsino:submit` DOM event is fired on the form’s iframe.

**Shortcode reference**

`[porsino form="14050620-3"]`

`[porsino form="14050620-3" mode="popup" label="Register" color="#0ea5e9" page="1" params="source=blog"]`

* `form` (required): the short code, the address or the full link of the form.
* `mode`: `inline` (default) or `popup`.
* `height`: initial height in pixels, only until the form loads (default 720).
* `label`, `color`: button text and colour.
* `base`: the forms address for this form only (for example your custom domain).
* `type`: `quiz` to show a quiz link (detected automatically with a connected account), or `form`.
* `utm`, `page`, `user`, `params`: see “Passing data into forms”.

The plugin loads no external scripts, styles or fonts and does no tracking of its own. Its small script and stylesheet are loaded only on pages that show a form.

= خلاصه‌ی فارسی =

افزونه‌ی رسمیِ [پرسینو](https://porsino.com) برای وردپرس: فرم، نظرسنجی و آزمون‌هایی را که در پرسینو ساخته‌اید با بلوکِ «فرمِ پرسینو»، کدِ کوتاهِ `[porsino]`، ابزارکِ المنتور یا دکمه‌ی «افزودن فرم پرسینو» در ویرایشگرِ کلاسیک در سایت بگذارید؛ درونِ صفحه با ارتفاعِ خودکار یا با دکمه‌ای که فرم را در پنجره باز می‌کند. آزمون همیشه در صفحه‌ی خودش و در زبانه‌ی تازه باز می‌شود.

* **دکمه‌ی شناور** و **پاپ‌آپِ خودکار** (پس از چند ثانیه، پس از پیمایشِ بخشی از صفحه یا هنگامِ خروج) در صفحه‌هایی که انتخاب می‌کنید؛ پاپ‌آپ برای ربات‌ها، روی پنجره‌ی دیگرِ پرسینو و پس از پاسخ‌دادن باز نمی‌شود.
* **ووکامرس:** فرم یا نظرسنجی در صفحه‌ی تشکر پس از خرید، با شماره‌ی سفارش.
* **اتصالِ حساب (اختیاری):** انتخابِ فرم از فهرست در ویرایشگرها، تشخیصِ خودکارِ آزمون و فرمِ منتشرنشده، و ابزارکِ «پرسینو» در پیشخوان با شمارِ پاسخ‌ها.
* **فرستادنِ داده به فرم (فقط با روشن‌کردنِ خودتان):** پارامترهای UTM، نشانی و عنوانِ صفحه، نام و ایمیلِ کاربرِ واردشده و مقدارهای ثابت؛ در پرسینو برایشان «فیلد مخفی» با منبعِ «پارامتر URL» و همان نام بگذارید.
* بی اسکریپت و فونتِ بیرونی و بی ردیابی؛ ترجمه‌ی کاملِ فارسی و پیشخوانِ راست‌به‌چپ.

== Installation ==

1. In WordPress go to Plugins › Add New and search for “Porsino Forms”, or upload `porsino-forms.zip` (also downloadable from the Share page of any form in Porsino) under Plugins › Add New › Upload Plugin.
2. Activate the plugin.
3. Add the “Porsino form” block, the Elementor widget, or the `[porsino form="…"]` shortcode (copy it from the form’s Share page in Porsino).
4. Optional: Settings › Porsino — set your custom domain, connect your Porsino account, and set up the floating button, the auto popup or the WooCommerce thank-you form.

== Frequently Asked Questions ==

= Do I need to connect my Porsino account? =

No. Connecting only adds the form picker, automatic quiz detection and the dashboard widget. Shortcodes, blocks, widgets and the site-wide features all work with a typed form address.

= I use my own domain for Porsino forms. Does it work? =

Yes. If you connected a custom domain in Porsino, enter it under Settings › Porsino › General (“Forms address”), or per form with `base="https://forms.example.com"`. The account connection always talks to porsino.com.

= Why does my quiz open in a new tab? =

Quizzes run on their own page: their server-side timer, sign-in and anti-cheating rules do not work inside another site’s frame. The plugin therefore shows a quiz as a button linking to it. With a connected account this is detected automatically; otherwise add `type="quiz"` (or choose “Quiz” as the kind in the block, widget or settings).

= How do I get the page address, UTM parameters or the user’s email into the form? =

Turn on the matching option (`utm`, `page`, `user` or `params`), then add a Hidden field to the form in Porsino with the value source “URL parameter” and the same parameter name (`utm_source`, `wp_page`, `wp_title`, `wp_name`, `wp_email`, `order_id`, … or your own key). Values without a matching hidden field are ignored.

= What does the plugin send to Porsino? Is it GDPR-friendly? =

Visitors’ browsers load the form from Porsino, like any embedded content, and submit their answers there. WordPress adds nothing about the visitor unless you enable a data-passing option for that form or feature. The auto popup remembers in the visitor’s own browser (local storage or a first-party cookie, with no identifier) when it was last shown. A suggested privacy-policy text is added to Settings › Privacy. Responses are stored in your Porsino account; WordPress stores none. Porsino’s own privacy policy: https://porsino.com/privacy

= The form is not displayed =

Make sure the form is published in Porsino and the address is correct. If you use a security plugin or a Content-Security-Policy header, `frame-src` must allow the forms address (for example `https://porsino.com`).

= The form height does not adjust =

Optimisation plugins that combine or delay scripts can break the plugin’s small script (`assets/porsino-forms.js`); exclude it from combining or delaying.

== External services ==

This plugin connects to **Porsino** (https://porsino.com), the service where the forms are built and the answers are stored. Terms of use: https://porsino.com/terms — Privacy policy: https://porsino.com/privacy

* **Showing a form.** On pages with a form, the visitor’s browser loads `https://porsino.com/embed/<form>` (or your custom domain) in an iframe — on page load for inline forms, or when the visitor opens a popup. Like any web request this sends the visitor’s IP address, browser details and the referring page. The query string carries only the values you enabled: `utm_*`, `wp_page`, `wp_title`, `wp_name`, `wp_email`, fixed `params`, and on the WooCommerce thank-you page `order_id` plus, if enabled, `order_total`, `customer_name` and `customer_email`. The visitor’s answers are submitted directly to Porsino.
* **Quizzes.** A quiz button links to `https://porsino.com/e/<form>` (same optional values); nothing is sent until the visitor clicks it.
* **Account connection (optional, administrators only).** “Connect to Porsino” sends the administrator’s browser to `https://porsino.com/connect/wordpress` with this site’s address, the settings page address to return to, a random one-time state and the plugin version. After approval, this site exchanges the one-time code with `POST https://porsino.com/api/v1/integrations/wordpress/token` (sending the code and the site address) and stores the returned key.
* **Using the connection (wp-admin only).** With the key, the plugin requests `GET /api/v1/integrations/wordpress/forms` (optional search text) to list your forms when an editor opens the block editor, the classic-editor dialog, the Elementor editor, the plugin settings or the dashboard (cached for five minutes); `GET /api/v1/integrations/wordpress/me` when you click “Check the connection”; and `DELETE /api/v1/integrations/wordpress/connection` when you disconnect or delete the plugin. These requests send the key and a `User-Agent` with the plugin version and the site address, and nothing about visitors. The public site never calls the API.

The API address can be changed with the `porsino_forms_api_base` filter.

== Changelog ==

= 2.0.0 =
* New: optional Porsino account connection (Settings › Porsino › Connect account) with a searchable form picker in the block editor, Elementor and the classic editor, a forms list, and automatic detection of quizzes and unpublished forms.
* New: live form preview in the block editor; quizzes and unpublished forms get a clear placeholder.
* New: quizzes are shown as a button that opens them on their own page in a new tab, never inside a frame (`type="quiz"`).
* New: Elementor widget “Porsino form”.
* New: “Add Porsino form” button in the classic editor.
* New: site-wide floating button with page targeting.
* New: site-wide auto popup (delay, scroll depth or exit intent; every visit, once per session or every few days) with page targeting.
* New: opt-in data passing into hidden fields: `utm`, `page`, `user` and `params`.
* New: WooCommerce thank-you page form with the order number and optional order total, customer name and email.
* New: “Porsino” dashboard widget with your latest forms and their response counts.
* New: suggested privacy-policy text; translation template (`porsino-forms.pot`); complete Persian translation.
* Existing shortcodes and blocks render exactly as before.

= 1.0.0 =
* First release: `[porsino]` shortcode, “Porsino form” block, inline and popup modes, custom domain, and the submit event for analytics.

== Upgrade Notice ==

= 2.0.0 =
Optional account connection with a form picker, Elementor widget, classic-editor button, floating button, auto popup, WooCommerce thank-you forms and opt-in data passing. Existing shortcodes and blocks keep working unchanged.
