=== DockAccess AI Alt Generator ===
Contributors: jacycha
Tags: accessibility, alt text, images, media, ai
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Generate alt text for images with AI from the media library, in the language of each image, synced with a DockAccess account.

== Description ==

DockAccess AI Alt Generator connects your WordPress site to a DockAccess account on dockaccess.org and lets you write alt text for images without leaving the media library.

One click next to the Alternative Text field generates a single alt text, writes it to the image straight away and keeps it in step with the alt text held in your DockAccess account.

**What makes it different**

Most alt text plugins stop at "call a model, paste the answer". This one is the WordPress end of an accessibility workflow that lives outside WordPress:

* **The alt text of a site is one shared set, not per-plugin state.** Every image goes into a single image set in the DockAccess account, keyed by the site token, so an editor, an auditor or another shop on the same account works on the same alt texts.
* **Alt text travels both ways.** An alt edited in WordPress is sent back to the account; an alt edited in the account is pushed into WordPress over a signed REST endpoint. Neither direction echoes the other, so the two never fight.
* **It writes in the language of the image, not the language of the site.** WPML and Polylang decide the language per media item, with a manual override per image and 85 languages available.
* **Bulk generation respects a quota instead of hitting a wall.** Images are sent one at a time; the run stops cleanly the moment the daily limit is reached, keeps everything already written and says where to pick up.
* **Only the picture leaves your server.** Every image is checked on your server before it is sent: it has to be a genuine JPEG, PNG, GIF, WebP or AVIF file, judged by its content rather than its name, and what goes out is a fresh copy made from its pixels alone - no EXIF, GPS position, camera serial, author, comments or anything appended to the file. Files with program code inside, SVG files and damaged files are refused on the spot and never sent.
* **It asks before it spends.** Before each generation the plugin checks with dockaccess.org whether the generator is still enabled for this site, and says which case it is - not enabled, or paused by the plan - instead of burning a request.

**Features**

* One-click generation right below the Alternative Text field - one alt text, applied and saved immediately
* Guided setup: get the site token, connect, generate - with links straight into your DockAccess account
* Plan, daily request usage and site count shown on the settings screen
* Bulk generation screen with every image of the library, paged, searchable and filterable to the images that have no alt text yet
* Alt texts edited in WordPress are sent back to the alt generator
* Alt texts edited elsewhere can be pushed into this site over a secret-protected endpoint
* Default context and tone in Settings → AI Alt Generator, overridable per image
* WPML and Polylang support with automatic language detection
* Tokens are kept out of plain sight in the options table and are never printed on screen
* Images are verified and re-encoded locally before they are sent, so no metadata leaves the site
* All requests to dockaccess.org are HTTPS only, with the certificate verified and redirects never followed

**Requirements**

* A DockAccess account on dockaccess.org with a site token - the plugin generates through that account and nothing else. The free plan is enough to start: one site and up to 10 alt texts a day.
* WordPress 6.0 or newer
* PHP 7.4 or newer

== External services ==

This plugin does not generate alt text on your server. It is the WordPress client of the DockAccess alt generator, an external service run by Dock Codes sp. z o.o. (dockaccess.org), and it cannot work without an account there. Two endpoints of that service are used.

**1. DockAccess connector API - https://dockaccess.org/fast-api**

Used to connect the site to your account, to check that the alt generator is still enabled for it, to disconnect it, and to send alt texts you edited in WordPress back to the account.

What is sent, and when:

* *When you press Connect on the settings screen:* the site token you pasted, your dockaccess.org login and password, the address of this site (`home_url`), the URL of this site's push endpoint, the WordPress version and the plugin version. The login and password are used for this one call and are never stored.
* *Before every generation, and when the settings screen is opened:* the site token and the connection secret. No login, no password.
* *After you edit the Alternative Text of an image that was generated through this plugin:* the identifier of that image in the account, the new alt text, its language, the site token and the account token.
* *When you press Disconnect:* the site token, your dockaccess.org login and password, and the address of this site.

**2. DockAccess alt generator API - https://alt.dockaccess.org**

Used to produce the alt text itself and to read the daily usage of the account.

What is sent, and when:

* *Every time you press Generate alt text, and once per image during a bulk run:* a copy of the image made on your server from its pixels alone - at most 2048 pixels on the longest side, without EXIF, GPS position, camera data, comments or anything else stored in the original file - the context text and tone from the settings (or the ones you set on that image), the target language, the account token and the site token. The image is analysed by an AI model on the service side to produce the description.
* *When the settings screen or the bulk screen shows the usage counter:* the account token only.

Nothing is sent to either endpoint until you connect the site. Until then the media library shows a note with a link to the connection screen instead of the generate button.

Use of the service is governed by the DockAccess terms of service and privacy policy:

* Terms of service: https://dockaccess.org/rules-regulations/regulations/
* Privacy policy: https://dockaccess.org/rules-regulations/privacy-policy/
* All DockAccess legal documents: https://dockaccess.org/rules-regulations/

== Installation ==

1. Upload the `dock-access-ai-alt-generator` folder to the `/wp-content/plugins/` directory, or install through the WordPress plugins screen.
2. Activate the plugin through the Plugins screen.
3. Go to Settings → AI Alt Generator → Connection and follow the three steps: open your sites on dockaccess.org to copy the site token, paste it here together with your account login and password, and press Connect.
4. Open any image in the media library and use the Generate alt text button next to the Alternative Text field.

Until the site is connected the media library shows a short note with a link to the connection screen instead of the generate button, and the plugin makes no calls to the service.

== Frequently Asked Questions ==

= Do I need an account somewhere else? =

Yes. Alt text is generated by the DockAccess alt generator on dockaccess.org, not on your server, so the plugin needs an account there and a site token from it. A free account is enough to start: it covers one site and up to 10 alt texts a day, and the paid plans raise those limits. See the "External services" section above for exactly what is sent and when.

= How does bulk generation handle my daily limit? =

Settings → AI Alt Generator → Bulk generation lists every image, with a filter for the ones that have no alt text yet, a page size and a pager. Tick the images and the plugin sends them **one at a time** - never several at once - writing each alt as it arrives.

The moment your account has no generations left for today, the run stops. The rows already done keep their new alt texts, the remaining ones are marked as not generated, and the summary says how far it got and links to the plans. Nothing is lost: pick up where it stopped tomorrow, or on a higher plan straight away.

The generator also accepts a limited number of requests per minute. That is not your daily limit, so the run simply waits it out and retries the same image instead of stopping.

= What happens when the alt generator is off for my site? =

Nothing is generated. Before each generation the plugin asks dockaccess.org whether the service is still on for this site (site token plus the connection secret - no login, no password), and the media panel shows what it heard back: the generator is not enabled for the site, or it is paused by the current plan. Connecting a site in that state is refused for the same reason, so a site is never half-connected.

If dockaccess.org itself cannot be reached, generation goes on rather than stopping the site over an outage - the alt generator API still checks the account behind it. Add `add_filter('dock_access_alt_generator_verify_blocks_generation', '__return_true');` if you would rather have it stop.

= What happens when the site is already connected? =

The plugin says so and asks for confirmation before replacing the connection. A replacement rotates the push secret, so any other copy of the plugin on the same address stops receiving alt updates. The same confirmation appears when dockaccess.org reports the address as connected.

= Are my dockaccess.org credentials stored? =

No. The login and password are used for the connect and disconnect calls only.

The site token, the account token and the push secret are kept in the options table, encoded with a key derived from the WordPress salts, and none of them is ever printed on screen - the connection screen shows the site token masked and nothing else. The encoding keeps the tokens out of plain sight in database dumps and exports; it is not a secret store, because anyone holding both wp-config.php and the database can decode them.

= Do alt edits in WordPress reach the alt generator? =

Yes, whenever the site is connected and the image was generated through the plugin. Editing the Alternative Text sends the new value to your DockAccess account after the save. A generated alt text is not sent back, and an alt text pushed to this site is not echoed either, so nothing can loop.

= Can dockaccess.org write alt texts into this site? =

Yes, through `/wp-json/dock-access-alt-generator/v1/alts`. Every request has to be signed with the push secret from the connection: an `X-Dockaccess-Signature` header carrying an HMAC-SHA256 of the timestamp and the request body, valid for five minutes. The secret itself is never sent, so it cannot be picked up from a log or a proxy, and a captured request cannot be re-pointed at a different alt text. The endpoint then writes the alt text matching the language of the media item.

Connection → Push endpoint → **Test the endpoint** sends a signed probe to your own site and tells you whether the route is reachable and the signature accepted - handy when a host blocks the REST API.

= What if an image was never generated here? =

Then the alt generator does not know it, and edits stay local. Generate the alt text once for that image and edits start syncing.

= How many alt texts does one generation produce? =

Exactly one. It is written to the image immediately - there is nothing to pick from.

= Is the plugin translated? =

The plugin is fully internationalised and translations are handled through translate.wordpress.org, so any locale the community translates is delivered by the normal WordPress update system - nothing to install by hand.

= Which media types are supported? =

JPEG, PNG, GIF, WebP and AVIF images. The type is read from the content of the file, never from its name, so a renamed file is recognised for what it is.

Everything else is refused before anything is sent: SVG (a document that can carry scripts), BMP, TIFF, files with program code inside, damaged files and images with more pixels than can be processed safely. The media panel says why.

= What exactly is sent for an image? =

Never the original file. The plugin reads it only from the uploads folder of this site, checks its whole structure, and sends a copy re-encoded from the pixels: turned the right way up, scaled down to at most 2048 pixels on the longest side, and without any metadata. A photo's GPS position, the camera serial number, the author, editing history, embedded thumbnails and anything appended to the file stay on your server. On a server without the GD extension the plugin removes the metadata from the file instead of re-encoding it.

= Is any third-party code included? =

The dockaccess alt generator PHP library by Dock Codes (MIT licence), in `vendor/dockcodes/dockaccess-alt-generator`, under this plugin's own namespace so it cannot clash with another plugin. It does the image checks and talks to the alt generator through the WordPress HTTP API.

= What does the plugin leave behind when I delete it? =

Nothing. Uninstalling removes the stored connection, the generation defaults and the per-image bookkeeping meta. The alt texts themselves stay on your images, because they are ordinary WordPress alt text.

== Screenshots ==

1. Generate alt text right in the media library: one click under the Alternative Text field writes the alt text to the image.
2. Bulk generation sends the selected images one at a time and saves each alt text as soon as it is ready.
3. The bulk screen after a run: every image with its new alt text, searchable and filterable to the images without one.
4. The connection screen: account, plan, daily usage and the signed push endpoint at a glance.
5. Three steps to connect: copy the site token from dockaccess.org, paste it with your login, generate.
6. Generation defaults: describe your site in up to 500 characters and pick one of 19 tones.
7. What the plugin does besides generating: language per image, two-way sync, quota-aware bulk runs and a clean uninstall.

== Changelog ==

= 1.0.1 =
* The plugin is now called DockAccess AI Alt Generator (was Dock Access AI Alt Generator). Same slug, settings and connection.
* Images are checked on the server before they are sent: only genuine JPEG, PNG, GIF, WebP and AVIF files, judged by their content. Files with program code inside, SVG, BMP, TIFF and damaged files are refused with a message saying why.
* The image sent to the generator is a copy re-encoded from its pixels, at most 2048 pixels on the longest side, so EXIF, GPS positions and other metadata never leave the site.
* Images are read only from the uploads folder of the site.
* Requests to dockaccess.org are HTTPS only and never follow a redirect, also when another plugin changes the default request settings.
* Alt texts received from dockaccess.org are cleaned of invisible direction overrides and zero-width characters.
* A rejected account token now stops a bulk run instead of failing every remaining image.

= 1.0.0 =
* Initial release.
